CUGL 2.3
Cornell University Game Library
Loading...
Searching...
No Matches
Public Member Functions | Friends | List of all members
cugl::audio::AudioInput Class Reference

#include <CUAudioInput.h>

Inheritance diagram for cugl::audio::AudioInput:
cugl::audio::AudioNode

Public Member Functions

void lock ()
 
void unlock ()
 
bool isLocked () const
 
 AudioInput ()
 
 ~AudioInput ()
 
const SDL_AudioDeviceID getAUID () const
 
const std::string getDevice () const
 
bool isDefault () const
 
Uint32 getWriteSize () const
 
void setWriteSize (Uint32 size)
 
Uint32 getReadDelay () const
 
void setReadDelay (Uint32 size)
 
virtual void setReadSize (Uint32 size) override
 
virtual bool pause () override
 
virtual bool resume () override
 
bool isRecording () const
 
bool release ()
 
bool acquire ()
 
void stop ()
 
std::shared_ptr< AudioSamplesave ()
 
virtual bool completed () override
 
virtual Uint32 read (float *buffer, Uint32 frames) override
 
Uint32 record (float *buffer, Uint32 frames)
 
void reboot ()
 
virtual bool mark () override
 
virtual bool unmark () override
 
virtual bool reset () 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 ()
 
virtual bool init ()
 
virtual bool init (Uint8 channels, Uint32 rate)
 
virtual void dispose ()
 
Uint8 getChannels () const
 
Uint32 getRate () const
 
float getGain ()
 
virtual void setGain (float gain)
 
Uint32 getReadSize () const
 
virtual void setReadSize (Uint32 size)
 
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 ()
 
virtual bool completed ()
 
virtual Uint32 read (float *buffer, Uint32 frames)
 
virtual bool mark ()
 
virtual bool unmark ()
 
virtual bool reset ()
 
virtual Sint64 advance (Uint32 frames)
 
virtual Sint64 getPosition () const
 
virtual Sint64 setPosition (Uint32 position)
 
virtual double getElapsed () const
 
virtual double setElapsed (double time)
 
virtual double getRemaining () const
 
virtual double setRemaining (double time)
 

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
static const Uint32 DEFAULT_CHANNELS
 
static const 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
 
Uint32 _readsize
 
std::string _localname
 
std::string _classname
 
size_t _hashOfName
 
bool _locked
 

Detailed Description

This class provides a graph node interface for an audio recording device.

This audio node provides a modern, graph-based approach to sound design. This input can be plugged into the audio graph and piped to the output device with a small (but significant) amount of latency. This node is intended to be the root of an audio DAG, much like AudioPlayer.

One of the important issues to understand about this class is that there are actually two different latency values: the recording latency and the playback latency. The recording latency is time from when the data is captured at the hardware device and is recorded at this node. It is entirely determined by the buffer size of this device, much like the buffer determines the playback latency for AudioOutput. However, unlike AudioOutput, there is no guarantee that recording happens at uniform time intervals. For example, on MacOS at 48000 Hz, a buffer size of 512 will record twice (in immediate sucession) every 21 ms instead of once every 11 ms (a buffer size of 1024 appers to record once every 21 ms as expected).

The playback latency is the time from when data is passed to record() and made available to read(); it does not include the latency of any output device. It is determined by the additional delay value, which is the number of frames that must be recorded before any can be read. So a delay of 0 means that data is instantly available, while a delay of the buffer size means that no data can be read until more than a single buffer has been recorded (which means that at least two buffers worth of data must have been recorded). Because output and input devices run in different threads and have no coordination at all, a delay of at least one buffer is recommended for real-time playback.

This method has no public initializers or non-degenerate constructors. That is because all input 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.

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

◆ AudioInput()

cugl::audio::AudioInput::AudioInput ( )

Creates a degenerate audio input 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.

◆ ~AudioInput()

cugl::audio::AudioInput::~AudioInput ( )

Deletes the audio input node, disposing of all resources

Member Function Documentation

◆ acquire()

bool cugl::audio::AudioInput::acquire ( )

Resumes recording for a previously released node.

This method does not effect playback. If playback is paused, then recording will be buffered if mark() is set, or else it will overwrite itself in the circular buffer.

If the node is already recording, this method has no effect.

Returns
true if the node was successfully acquired

◆ completed()

virtual bool cugl::audio::AudioInput::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, input nodes may run infinitely. Therefore this method only returns true when either of the methods stop() or setRemaining() are called.

Returns
true if this audio node has no more data.

Reimplemented from cugl::audio::AudioNode.

◆ getAUID()

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

Returns the audio device identifier associated with this audio input.

Returns
the audio device identifier associated with this audio input.

◆ getDevice()

const std::string cugl::audio::AudioInput::getDevice ( ) const

Returns the device associated with this input node.

Returns
the device associated with this input node.

◆ getElapsed()

virtual double cugl::audio::AudioInput::getElapsed ( ) const
overridevirtual

Returns the elapsed time in seconds.

This method returns -1 (indicating it is not supported) if mark() is not set. Otherwise, the position will be the number of seconds since the mark.

Returns
the elapsed time in seconds.

Reimplemented from cugl::audio::AudioNode.

◆ getPosition()

virtual Sint64 cugl::audio::AudioInput::getPosition ( ) const
overridevirtual

Returns the current frame position of this audio node

This method returns -1 (indicating it is not supported) if mark() is not set. Otherwise, the position will be the number of frames since the mark.

Returns
the current frame position of this audio node.

Reimplemented from cugl::audio::AudioNode.

◆ getReadDelay()

Uint32 cugl::audio::AudioInput::getReadDelay ( ) const
inline

Returns the additional read delay of this input node.

Most of the time, a delay of the read size is enough. However, sometimes an additional delay is required for performance reasons. This playback delay is added on top of the normal read size delay. By default, this value is 0.

Changing this value will temporarily lock this input device.

Returns
the additional read delay of this input node.

◆ getRemaining()

virtual double cugl::audio::AudioInput::getRemaining ( ) const
overridevirtual

Returns the remaining time in seconds.

This method returns -1 (indicating it is not supported) if the method setRemaining() has not been called or has been interrupted. Otherwise, it returns the amount of time left in the countdown timer until this node completes.

Returns
the remaining time in seconds.

Reimplemented from cugl::audio::AudioNode.

◆ getWriteSize()

Uint32 cugl::audio::AudioInput::getWriteSize ( ) const
inline

Returns the write size of this input node.

The buffer value is the number of samples recorded at each poll. Smaller buffers clearly tax the CPU, as the device is collecting data at a higher rate. Furthermore, if the value is too small, the recording device may not be able to keep up with the output device. For example, we find on MacOS that the input device at a sample rate of 48000 Hz can only record stereo data every 21 milliseconds. Hence so it can only (at best) keep up with a 512 frame playback buffer.

This method is not synchronized as it can only be changed by locking the input device.

Returns
the write size of this input node.

◆ isDefault()

bool cugl::audio::AudioInput::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

◆ isLocked()

bool cugl::audio::AudioInput::isLocked ( ) const
inline

Returns true if the input device is currently locked.

A locked input device cannot record. However, it will still respond to read events if it is in an audio graph. This method will have no effect if the device is not locked.

Returns
true if the input device is currently locked.

◆ isRecording()

bool cugl::audio::AudioInput::isRecording ( ) const

Returns true if this node is currently recording audio.

Recording is completely independent of playback. An input node can be recording, but have its played paused, and vice versa.

Returns
true if this node is currently recording audio.

◆ lock()

void cugl::audio::AudioInput::lock ( )

Temporarily locks this input device

A locked input device cannot record. However, it will still respond to read events if it is in an audio graph. This method will have no effect if the device is already locked.

IMPORTANT: You must call unlock on this device to use it again. The device will only unlock itself on destruction.

◆ mark()

virtual bool cugl::audio::AudioInput::mark ( )
overridevirtual

Marks the current read position in the audio steam.

This methods creates an internal buffer for recording audio data. This buffer may be returned to at any time with reset() command. Doing so introduces an inherent delay going forward, as the playback comes from the recorded buffer.

Returns
true if the read position was marked.

Reimplemented from cugl::audio::AudioNode.

◆ pause()

virtual bool cugl::audio::AudioInput::pause ( )
overridevirtual

Pauses this node, preventing any data from being played back.

As with all other audio nodes, pausing effects the playback. However, it does not affect recording. Recording will still happen in the background and may be recovered if mark() is set. To stop recording (but not playback) call release() instead.

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::AudioInput::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. The number of frames read is determined by the audio graph, not the buffer of this device.

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::AudioInput::reboot ( )

Reboots the audio input 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.

◆ record()

Uint32 cugl::audio::AudioInput::record ( float *  buffer,
Uint32  frames 
)

Records the specified number of frames to this audio node

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.

If mark() is not set, this method records to a circular buffer that has the given getWriteSize(). Data that is not read in a timely manner is lost from the buffer.

However, if mark is set, then this method writes to an ever-increasing queue. This queue can be accessed at any time with reset() or setPosition(). This can potentially take a lot of memory and so it should be used carefully. Use release() to stop recording to the buffer while still having access to it.

◆ release()

bool cugl::audio::AudioInput::release ( )

Stops this input node from recording.

This method does not effect playback. Unpaused playback will continue until the write delay has caught up. After that point, it will only play silence.

If the node is not recording, this method has no effect.

Returns
true if the node was successfully released

◆ reset()

virtual bool cugl::audio::AudioInput::reset ( )
overridevirtual

Resets the read position to the marked position of the audio stream.

This method does nothing (and returns false) if no mark() is set. Otherwise, it resets to the start of the buffer created by the call to mark. This introduces an inherent delay going forward, as the playback comes from the recorded buffer.

Returns
true if the read position was moved.

Reimplemented from cugl::audio::AudioNode.

◆ resume()

virtual bool cugl::audio::AudioInput::resume ( )
overridevirtual

Resumes this previously paused node, allowing data to be played back.

As with all other audio nodes, pausing effects the playback. However, does not affect recording. When play is resumed, the playback will either return with immediate playback or the recording buffer, depending on whether mark() is set.

If the node is not paused, this method has no effect.

Returns
true if the node was successfully resumed

Reimplemented from cugl::audio::AudioNode.

◆ save()

std::shared_ptr< AudioSample > cugl::audio::AudioInput::save ( )

Returns any cached data as an in-memory audio sample.

This method is potentially expensive and should only be called when the audio node has stopped recording (via the release() method, and when the node is not part of an audio graph giving real-time playback.

If mark() is not set, this will return null rather than return an empty audio sample.

Returns
any cached data as an in-memory audio sample.

◆ setElapsed()

virtual double cugl::audio::AudioInput::setElapsed ( double  time)
overridevirtual

Sets the read position to the elapsed time in seconds.

This method returns -1 (indicating it is not supported) if mark() is not set. Otherwise, it will set the position to the number of seconds since the mark. If the position is in the future (a time not already buffered) then this method will fail and return -1.

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

Reimplemented from cugl::audio::AudioNode.

◆ setPosition()

virtual Sint64 cugl::audio::AudioInput::setPosition ( Uint32  position)
overridevirtual

Sets the current frame position of this audio node.

This method returns -1 (indicating it is not supported) if mark() is not set. Otherwise, it will set the position to the number of frames since the mark. If the position is in the future (a frame not already buffered) then this method will fail and return -1.

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

Reimplemented from cugl::audio::AudioNode.

◆ setReadDelay()

void cugl::audio::AudioInput::setReadDelay ( Uint32  size)

Returns the write size of this input node.

Most of the time, a delay of the read size is enough. However, sometimes an additional delay is required for performance reasons. This playback delay is added on top of the normal read size delay. By default, this value is 0.

Changing this value will temporarily lock this input device.

Parameters
sizeThe additional read delay of this input node.

◆ setReadSize()

virtual void cugl::audio::AudioInput::setReadSize ( Uint32  size)
overridevirtual

Sets the read size of this input node.

The read size determines the minimal delay of this input node. All audio is guaranteed to be delay by one read size cycle.

Changing this value will temporarily lock this input device.

Parameters
sizeThe read size of this input node.

Reimplemented from cugl::audio::AudioNode.

◆ setRemaining()

virtual double cugl::audio::AudioInput::setRemaining ( double  time)
overridevirtual

Sets the remaining time in seconds.

This method sets a countdown timer on the input node, forcing it to complete in the given number of seconds. If the audio has been reading from the buffer (because of a call to setPosition(), this method immediately skips ahead to real-time recording. Any call to setPosition() or setElapsed() before this time is up will cancel the countdown.

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

Reimplemented from cugl::audio::AudioNode.

◆ setWriteSize()

void cugl::audio::AudioInput::setWriteSize ( Uint32  size)

Sets the write size of this input node.

The buffer value is the number of samples recorded at each poll. Smaller buffers clearly tax the CPU, as the device is collecting data at a higher rate. Furthermore, if the value is too small, the recording device may not be able to keep up with the output device. For example, we find on MacOS that the input device at a sample rate of 48000 Hz can only record stereo data every 21 milliseconds. Hence so it can only (at best) keep up with a 512 frame playback buffer.

Changing this value will temporarily lock this input device.

Parameters
sizeThe write size of this input node.

◆ stop()

void cugl::audio::AudioInput::stop ( )

Instantly stops this node from both recording and playback.

This method is the same as calling both the methods pause() and release(). In addition, the input node will be marked as completed() for the purpose of the audio graph.

◆ unlock()

void cugl::audio::AudioInput::unlock ( )

Unlocks this input device

A locked input device cannot record. However, it will still respond to read events if it is in an audio graph. This method will have no effect if the device is not locked.

◆ unmark()

virtual bool cugl::audio::AudioInput::unmark ( )
overridevirtual

Clears the current marked position.

If the method mark() has started recording to a buffer, then this method will stop recording and release the buffer. When the mark is cleared the method reset() will no longer work.

Returns
true if the read position was marked.

Reimplemented from cugl::audio::AudioNode.

Friends And Related Function Documentation

◆ cugl::AudioDevices

friend class cugl::AudioDevices
friend

Allow AudioManager to access intializers


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