CUGL 2.1
Cornell University Game Library
Public Types | Public Member Functions | Static Public Member Functions | List of all members
cugl::audio::AudioSpinner Class Reference

#include <CUAudioSpinner.h>

Inheritance diagram for cugl::audio::AudioSpinner:
cugl::audio::AudioNode

Public Types

enum  Plan : int {
  MONAURAL = 0, FRONT_STEREO = 1, SIDE_STEREO = 2, FRONT_CENTER = 3,
  SIDE_CENTER = 4, FRONT_QUADS = 5, CORNER_QUADS = 6, BACK_5_1 = 7,
  SIDE_5_1 = 8, CORNER_5_1 = 9, BACK_7_1 = 10, CORNER_7_1 = 11,
  CUSTOM = 12
}
 
- 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 Member Functions

 AudioSpinner ()
 
 ~AudioSpinner ()
 
virtual bool init () override
 
virtual bool init (Uint8 channels, Uint32 rate) override
 
bool init (Uint8 channels, Uint8 field, Uint32 rate)
 
virtual void dispose () override
 
bool attach (const std::shared_ptr< AudioNode > &node)
 
std::shared_ptr< AudioNodedetach ()
 
std::shared_ptr< AudioNodegetInput ()
 
Plan getFieldPlan () const
 
void setFieldPlan (Plan plan)
 
Plan getChannelPlan () const
 
void setChannelPlan (Plan plan)
 
float getFieldOrientation (Uint32 channel) const
 
void setFieldOrientation (Uint32 channel, float angle)
 
float getChannelOrientation (Uint32 channel) const
 
void setChannelOrientation (Uint32 channel, float angle)
 
float getSubwoofer () const
 
void setSubwoofer (float frequency)
 
float getAngle () const
 
void setAngle (float angle)
 
virtual bool completed () override
 
virtual Uint32 read (float *buffer, Uint32 frames) override
 
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 ()
 
virtual bool pause ()
 
virtual bool resume ()
 

Static Public Member Functions

static std::shared_ptr< AudioSpinneralloc ()
 
static std::shared_ptr< AudioSpinneralloc (Uint8 channels, Uint32 rate)
 
static std::shared_ptr< AudioSpinneralloc (Uint8 channels, Uint8 field, Uint32 rate)
 

Additional Inherited Members

- 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
 

Detailed Description

A class representing a spatial audio panner.

This audio node takes another audio node as input. That node must agree with the sample rate of this node, but need not have the same number of channels. In fact, the input node must instead have getFieldPlan() number of channels. It then maps the data from this input channels to the output channels.

This mapping happens according to an angle, which specifies the direction of the sound source (not the listener). An angle of 0 means the sound is coming from straight ahead, and the sound should map to the natural output channels. An angle of PI/2 means the sound is centered directly to the left, and the output channels should be adjusted accordingly.

To properly pan the audio, this node needs to know the location of all of the output channels in the room, specified as an angle (with 0 being straight ahead – the traditional center channel). There are several built-in options for specifying the channels. These are taken from

http://www.wendycarlos.com/surround/

However, the user can specify the channel locations manually using the setChannelOrientation() method.

There are separate plans for both to the audio input and the ouput. This is how the node knows how to handle rotation of non-monaural sounds.

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.

Member Enumeration Documentation

◆ Plan

This enum represents the possible surround-sound layouts.

Most of these layouts are taken from personal experience or from

http://www.wendycarlos.com/surround/

They should not be taken as exhaustive. This list may be modified at any time. For that reason, you should never refer to a layout plan by its raw number.

Enumerator
MONAURAL 

Single channel monaural sound.

The only channel is straight ahead at 0 degrees.

FRONT_STEREO 

Stereo sound in front of the listener.

The left and right channels are separated by 60 degrees (so at +30 and -30 degrees in front of the listener). This is typical for a stereo set-up associated with a display (e.g. a TV).

SIDE_STEREO 

Stereo sound to the sides of the listener.

The left and right channels are separated by 180 degrees (so at +90 and -90 degrees). This is the classic headphones set-up.

FRONT_CENTER 

Three channel sound in front of the listener.

The left and right channels are separated by 90 degrees (so at +45 and -45 degrees in front of the listener), while the center channel is at 0 degrees. This is typical for a three channels set-up associated with a display (e.g. a TV).

SIDE_CENTER 

Three channel sound to the sides of the listener.

The left and right channels are separated by 180 degrees (so at +90 and -90 degrees), while the center channel is at 0 degrees. This is a less typical display setup.

FRONT_QUADS 

Four channel sound favoring the font and back.

The front left and right channels are separated by 60 degrees, just as with FRONT_STEREO. The back left an right channels are also separated by 60 degrees, centered at 180 degrees behind the listener. This is a quad set-up that minimizes "black holes" in the sound field at the expense of sound on the sides.

CORNER_QUADS 

Four channel sound equi-spaced.

All four channes are separated by 90 degrees about the circle, with 0 degrees equidistant between the left and right channel. This creates a uniform sound field, but can create "black holes" between output channels.

BACK_5_1 

Five channel sound (with subwoofer) with surrounds at the back.

The first three channels are arranged as in FRONT_CENTER. The rears are separated by 60 degrees, centered at 180 degrees behind the listener. In this case, the surround gives rear information only.

SIDE_5_1 

Five channel sound (with subwoofer) with surrounds at the sides.

The first three channels are arranged as in FRONT_CENTER. The rears are separated by 180 degrees, with left rear at 90 degrees and right rear at 180 degrees. In this case, the surround gives side sound information.

CORNER_5_1 

Five channel sound (with subwoofer) with surrounds in the corner.

The first three channels are arranged as in FRONT_CENTER. The rears are separated by 90 degrees, centered at 180 degrees behind the listener. This is an attempted compromise between back and side 5.1 set-ups.

BACK_7_1 

Seven channel sound (with subwoofer) with surrounds at the back.

The first three channels are arranged as in FRONT_CENTER, and the last two channels are arranged at the sides separated by 180 degrees. The two intermediate surround channels are separated by 60 degrees, centered at 180 degrees behind the listener. This is an attempt to give a tight surround experience.

CORNER_7_1 

Seven channel sound (with subwoofer) with surrounds at the back.

The first three channels are arranged as in FRONT_CENTER, and the last two channels are arranged at the sides separated by 180 degrees. The two intermediate surround channels are separated by 90 degrees, centered at 180 degrees behind the listener. This is an attempt to give a more diffuse surround experience.

CUSTOM 

A custom layout plan. s This type is used whenever the user expects to set their own layout orientations.

Constructor & Destructor Documentation

◆ AudioSpinner()

cugl::audio::AudioSpinner::AudioSpinner ( )

Creates a degenerate audio spinner.

The node has no channels, so read options will do nothing. The node must be initialized to be used.

NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate a graph node on the heap, use one of the static constructors instead.

◆ ~AudioSpinner()

cugl::audio::AudioSpinner::~AudioSpinner ( )
inline

Deletes the audio spinner, disposing of all resources

Member Function Documentation

◆ advance()

virtual Sint64 cugl::audio::AudioSpinner::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.

◆ alloc() [1/3]

static std::shared_ptr<AudioSpinner> cugl::audio::AudioSpinner::alloc ( )
inlinestatic

Returns a newly allocated spinner with the default stereo settings

The number of channels is two, for stereo output. The sample rate is the modern standard of 48000 HZ. The spinner will start with left and right mapped to the appropriate locations.

Returns
a newly allocated spinner with the default stereo settings

◆ alloc() [2/3]

static std::shared_ptr<AudioSpinner> cugl::audio::AudioSpinner::alloc ( Uint8  channels,
Uint32  rate 
)
inlinestatic

Returns a newly allocated spinner with the given number of channels and sample rate

The field will be the same as the number of channels. By default, each input channel will map to itself as an output channel (until the angle changes). Both the input and output will share the same (default) layout plan.

Parameters
channelsThe number of audio channels
rateThe sample rate (frequency) in HZ
Returns
a newly allocated spinner with the given number of channels and sample rate

◆ alloc() [3/3]

static std::shared_ptr<AudioSpinner> cugl::audio::AudioSpinner::alloc ( Uint8  channels,
Uint8  field,
Uint32  rate 
)
inlinestatic

Returns a newly allocated spinner with the given number of input/output channels.

The number of input channels is given by field, while channels is the number of output channels. The input and output will each have the default layout plan for the given size.

Parameters
channelsThe number of output channels
fieldThe number of input channels
rateThe sample rate (frequency) in HZ
Returns
a newly allocated spinner with the given number of input/output channels.

◆ attach()

bool cugl::audio::AudioSpinner::attach ( const std::shared_ptr< AudioNode > &  node)

Attaches an audio node to this spinner.

This method will fail if the channels of the audio node do not agree with the field size of this panner

Parameters
nodeThe audio node to pan
Returns
true if the attachment was successful

◆ completed()

virtual bool cugl::audio::AudioSpinner::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::AudioSpinner::detach ( )

Detaches an audio node from this spinner.

If the method succeeds, it returns the audio node that was removed.

Returns
The audio node to detach (or null if failed)

◆ dispose()

virtual void cugl::audio::AudioSpinner::dispose ( )
overridevirtual

Disposes any resources allocated for this spinner.

The state of the node is reset to that of an uninitialized constructor. Unlike the destructor, this method allows the node to be reinitialized.

Reimplemented from cugl::audio::AudioNode.

◆ getAngle()

float cugl::audio::AudioSpinner::getAngle ( ) const

Returns the angle of the sound source.

If this angle is not 0, the input orientation will be rotated by the given angle to align it with the output orientation. Input channels that are between two output channels will be interpolated.

Returns
the angle of the sound source.

◆ getChannelOrientation()

float cugl::audio::AudioSpinner::getChannelOrientation ( Uint32  channel) const

Returns the orientation of an output channel.

Parameters
channelThe output channel
Returns
the orientation of an output channel.

◆ getChannelPlan()

Plan cugl::audio::AudioSpinner::getChannelPlan ( ) const

Returns the layout plan for the audio output.

This is the layout of the output channels.

Returns
the layout plan for the audio output.

◆ getElapsed()

virtual double cugl::audio::AudioSpinner::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.

◆ getFieldOrientation()

float cugl::audio::AudioSpinner::getFieldOrientation ( Uint32  channel) const

Returns the orientation of an input channel.

This is the intended layout of the sound source, unrotated.

Parameters
channelThe input channel
Returns
the orientation of an input channel.

◆ getFieldPlan()

Plan cugl::audio::AudioSpinner::getFieldPlan ( ) const

Returns the layout plan for the audio input.

This is the intended layout of the sound source, unrotated.

Returns
the layout plan for the audio input.

◆ getInput()

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

Returns the input node of this spinner.

Returns
the input node of this spinner.

◆ getPosition()

virtual Sint64 cugl::audio::AudioSpinner::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::AudioSpinner::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.

◆ getSubwoofer()

float cugl::audio::AudioSpinner::getSubwoofer ( ) const

Returns the crossover frequency (in Hz) for the subwoofer.

Sounds below this frequency will be sent to the subwoofer, regardless of the input channel.

Returns
the crossover frequency (in Hz) for the subwoofer.

◆ init() [1/3]

virtual bool cugl::audio::AudioSpinner::init ( )
overridevirtual

Initializes the node with default stereo settings

The number of channels is two, for stereo output. The sample rate is the modern standard of 48000 HZ. The spinner will start with left and right mapped to the appropriate locations.

Returns
true if initialization was successful

Reimplemented from cugl::audio::AudioNode.

◆ init() [2/3]

virtual bool cugl::audio::AudioSpinner::init ( Uint8  channels,
Uint32  rate 
)
overridevirtual

Initializes the node with the given number of channels and sample rate

The field will be the same as the number of channels. By default, each input channel will map to itself as an output channel (until the angle changes). Both the input and output will share the same (default) layout plan.

Parameters
channelsThe number of audio channels
rateThe sample rate (frequency) in HZ
Returns
true if initialization was successful

Reimplemented from cugl::audio::AudioNode.

◆ init() [3/3]

bool cugl::audio::AudioSpinner::init ( Uint8  channels,
Uint8  field,
Uint32  rate 
)

Initializes the node with the given number of input/output channels.

The number of input channels is given by field, while channels is the number of output channels. The input and output will each have the default layout plan for the given size.

Parameters
channelsThe number of output channels
fieldThe number of input channels
rateThe sample rate (frequency) in HZ
Returns
true if initialization was successful

◆ mark()

virtual bool cugl::audio::AudioSpinner::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.

◆ read()

virtual Uint32 cugl::audio::AudioSpinner::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.

◆ reset()

virtual bool cugl::audio::AudioSpinner::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.

◆ setAngle()

void cugl::audio::AudioSpinner::setAngle ( float  angle)

Sets the angle of the sound source.

If this angle is not 0, the input orientation will be rotated by the given angle to align it with the output orientation. Input channels that are between two output channels will be interpolated.

Parameters
angleThe angle of the sound source.

◆ setChannelOrientation()

void cugl::audio::AudioSpinner::setChannelOrientation ( Uint32  channel,
float  angle 
)

Sets the orientation of an output channel.

Parameters
channelThe output channel
angleThe angle from the listener's forward position.
Returns
the orientation of an output channel.

◆ setChannelPlan()

void cugl::audio::AudioSpinner::setChannelPlan ( Plan  plan)

Sets the layout plan for the audio output.

This is the layout of the output channels. If the value is CUSTOM, the current orientations will not be affected. Instead, the user should set the orientations manually.

Parameters
planThe layout plan for the audio output.

◆ setElapsed()

virtual double cugl::audio::AudioSpinner::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.

◆ setFieldOrientation()

void cugl::audio::AudioSpinner::setFieldOrientation ( Uint32  channel,
float  angle 
)

Sets the orientation of an input channel.

This is the intended layout of the sound source, unrotated.

Parameters
channelThe input channel
angleThe angle from the listener's forward position.
Returns
the orientation of an input channel.

◆ setFieldPlan()

void cugl::audio::AudioSpinner::setFieldPlan ( Plan  plan)

Sets the layout plan for the audio input.

This is the intended layout of the sound source, unrotated. If the value is CUSTOM, the current orientations will not be affected. Instead, the user should set the orientations manually.

Parameters
planThe layout plan for the audio input.

◆ setPosition()

virtual Sint64 cugl::audio::AudioSpinner::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::AudioSpinner::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.

◆ setSubwoofer()

void cugl::audio::AudioSpinner::setSubwoofer ( float  frequency)

Sets the crossover frequency (in Hz) for the subwoofer.

Sounds below this frequency will be sent to the subwoofer, regardless of the input channel.

Parameters
frequencyThe crossover frequency (in Hz) for the subwoofer.

◆ unmark()

virtual bool cugl::audio::AudioSpinner::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.


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