CUGL 2.3
Cornell University Game Library
|
#include <CUAudioInput.h>
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< AudioSample > | save () |
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 |
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
.
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
.
cugl::audio::AudioInput::~AudioInput | ( | ) |
Deletes the audio input node, disposing of all resources
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.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
inline |
Returns the audio device identifier associated with this audio input.
const std::string cugl::audio::AudioInput::getDevice | ( | ) | const |
Returns the device associated with this input node.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
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.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
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.
|
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.
|
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.
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.
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.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
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.
buffer | The read buffer to store the results |
frames | The maximum number of frames to read |
Reimplemented from cugl::audio::AudioNode.
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.
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.
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.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
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.
Reimplemented from cugl::audio::AudioNode.
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.
|
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.
time | The elapsed time in seconds. |
Reimplemented from cugl::audio::AudioNode.
|
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.
position | the current frame position of this audio node. |
Reimplemented from cugl::audio::AudioNode.
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.
size | The additional read delay of this input node. |
|
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.
size | The read size of this input node. |
Reimplemented from cugl::audio::AudioNode.
|
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.
time | The remaining time in seconds. |
Reimplemented from cugl::audio::AudioNode.
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.
size | The write size of this input node. |
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.
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.
|
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.
Reimplemented from cugl::audio::AudioNode.
|
friend |
Allow AudioManager to access intializers