summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/webaudio/AudioNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/webaudio/AudioNode.cpp')
-rw-r--r--Source/WebCore/Modules/webaudio/AudioNode.cpp205
1 files changed, 98 insertions, 107 deletions
diff --git a/Source/WebCore/Modules/webaudio/AudioNode.cpp b/Source/WebCore/Modules/webaudio/AudioNode.cpp
index 514ec7a3e..d0d42335f 100644
--- a/Source/WebCore/Modules/webaudio/AudioNode.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioNode.cpp
@@ -42,7 +42,7 @@
namespace WebCore {
-AudioNode::AudioNode(AudioContext* context, float sampleRate)
+AudioNode::AudioNode(AudioContext& context, float sampleRate)
: m_isInitialized(false)
, m_nodeType(NodeTypeUnknown)
, m_context(context)
@@ -67,6 +67,7 @@ AudioNode::AudioNode(AudioContext* context, float sampleRate)
AudioNode::~AudioNode()
{
+ ASSERT(isMainThread());
#if DEBUG_AUDIONODE_REFERENCES
--s_nodeCount[nodeType()];
fprintf(stderr, "%p: %d: AudioNode::~AudioNode() %d %d\n", this, nodeType(), m_normalRefCount.load(), m_connectionRefCount);
@@ -100,12 +101,12 @@ void AudioNode::lazyInitialize()
void AudioNode::addInput(std::unique_ptr<AudioNodeInput> input)
{
- m_inputs.append(std::move(input));
+ m_inputs.append(WTFMove(input));
}
void AudioNode::addOutput(std::unique_ptr<AudioNodeOutput> output)
{
- m_outputs.append(std::move(output));
+ m_outputs.append(WTFMove(output));
}
AudioNodeInput* AudioNode::input(unsigned i)
@@ -122,117 +123,103 @@ AudioNodeOutput* AudioNode::output(unsigned i)
return nullptr;
}
-void AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsigned inputIndex, ExceptionCode& ec)
+ExceptionOr<void> AudioNode::connect(AudioNode& destination, unsigned outputIndex, unsigned inputIndex)
{
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
-
- if (!destination) {
- ec = SYNTAX_ERR;
- return;
- }
+ AudioContext::AutoLocker locker(context());
// Sanity check input and output indices.
- if (outputIndex >= numberOfOutputs()) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (outputIndex >= numberOfOutputs())
+ return Exception { INDEX_SIZE_ERR };
- if (destination && inputIndex >= destination->numberOfInputs()) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (inputIndex >= destination.numberOfInputs())
+ return Exception { INDEX_SIZE_ERR };
- if (context() != destination->context()) {
- ec = SYNTAX_ERR;
- return;
- }
+ if (context() != destination.context())
+ return Exception { SYNTAX_ERR };
- AudioNodeInput* input = destination->input(inputIndex);
- AudioNodeOutput* output = this->output(outputIndex);
+ auto* input = destination.input(inputIndex);
+ auto* output = this->output(outputIndex);
input->connect(output);
// Let context know that a connection has been made.
- context()->incrementConnectionCount();
+ context().incrementConnectionCount();
+
+ return { };
}
-void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionCode& ec)
+ExceptionOr<void> AudioNode::connect(AudioParam& param, unsigned outputIndex)
{
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
+ AudioContext::AutoLocker locker(context());
- if (!param) {
- ec = SYNTAX_ERR;
- return;
- }
+ if (outputIndex >= numberOfOutputs())
+ return Exception { INDEX_SIZE_ERR };
- if (outputIndex >= numberOfOutputs()) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (context() != param.context())
+ return Exception { SYNTAX_ERR };
- if (context() != param->context()) {
- ec = SYNTAX_ERR;
- return;
- }
+ auto* output = this->output(outputIndex);
+ param.connect(output);
- AudioNodeOutput* output = this->output(outputIndex);
- param->connect(output);
+ return { };
}
-void AudioNode::disconnect(unsigned outputIndex, ExceptionCode& ec)
+ExceptionOr<void> AudioNode::disconnect(unsigned outputIndex)
{
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
+ AudioContext::AutoLocker locker(context());
// Sanity check input and output indices.
- if (outputIndex >= numberOfOutputs()) {
- ec = INDEX_SIZE_ERR;
- return;
- }
+ if (outputIndex >= numberOfOutputs())
+ return Exception { INDEX_SIZE_ERR };
- AudioNodeOutput* output = this->output(outputIndex);
+ auto* output = this->output(outputIndex);
output->disconnectAll();
+
+ return { };
}
-unsigned long AudioNode::channelCount()
+unsigned AudioNode::channelCount()
{
return m_channelCount;
}
-void AudioNode::setChannelCount(unsigned long channelCount, ExceptionCode& ec)
+ExceptionOr<void> AudioNode::setChannelCount(unsigned channelCount)
{
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
+ AudioContext::AutoLocker locker(context());
- if (channelCount > 0 && channelCount <= AudioContext::maxNumberOfChannels()) {
- if (m_channelCount != channelCount) {
- m_channelCount = channelCount;
- if (m_channelCountMode != Max)
- updateChannelsForInputs();
- }
- } else
- ec = INVALID_STATE_ERR;
+ if (!(channelCount > 0 && channelCount <= AudioContext::maxNumberOfChannels()))
+ return Exception { INVALID_STATE_ERR };
+
+ if (m_channelCount == channelCount)
+ return { };
+
+ m_channelCount = channelCount;
+ if (m_channelCountMode != Max)
+ updateChannelsForInputs();
+ return { };
}
String AudioNode::channelCountMode()
{
switch (m_channelCountMode) {
case Max:
- return "max";
+ return ASCIILiteral("max");
case ClampedMax:
- return "clamped-max";
+ return ASCIILiteral("clamped-max");
case Explicit:
- return "explicit";
+ return ASCIILiteral("explicit");
}
ASSERT_NOT_REACHED();
- return "";
+ return emptyString();
}
-void AudioNode::setChannelCountMode(const String& mode, ExceptionCode& ec)
+ExceptionOr<void> AudioNode::setChannelCountMode(const String& mode)
{
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
+ AudioContext::AutoLocker locker(context());
ChannelCountMode oldMode = m_channelCountMode;
@@ -243,41 +230,45 @@ void AudioNode::setChannelCountMode(const String& mode, ExceptionCode& ec)
else if (mode == "explicit")
m_channelCountMode = Explicit;
else
- ec = INVALID_STATE_ERR;
+ return Exception { INVALID_STATE_ERR };
if (m_channelCountMode != oldMode)
updateChannelsForInputs();
+
+ return { };
}
String AudioNode::channelInterpretation()
{
switch (m_channelInterpretation) {
case AudioBus::Speakers:
- return "speakers";
+ return ASCIILiteral("speakers");
case AudioBus::Discrete:
- return "discrete";
+ return ASCIILiteral("discrete");
}
ASSERT_NOT_REACHED();
- return "";
+ return emptyString();
}
-void AudioNode::setChannelInterpretation(const String& interpretation, ExceptionCode& ec)
+ExceptionOr<void> AudioNode::setChannelInterpretation(const String& interpretation)
{
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
+ AudioContext::AutoLocker locker(context());
if (interpretation == "speakers")
m_channelInterpretation = AudioBus::Speakers;
else if (interpretation == "discrete")
m_channelInterpretation = AudioBus::Discrete;
else
- ec = INVALID_STATE_ERR;
+ return Exception { INVALID_STATE_ERR };
+
+ return { };
}
void AudioNode::updateChannelsForInputs()
{
- for (unsigned i = 0; i < m_inputs.size(); ++i)
- input(i)->changedOutputs();
+ for (auto& input : m_inputs)
+ input->changedOutputs();
}
EventTargetInterface AudioNode::eventTargetInterface() const
@@ -287,12 +278,12 @@ EventTargetInterface AudioNode::eventTargetInterface() const
ScriptExecutionContext* AudioNode::scriptExecutionContext() const
{
- return const_cast<AudioNode*>(this)->context()->scriptExecutionContext();
+ return const_cast<AudioNode*>(this)->context().scriptExecutionContext();
}
void AudioNode::processIfNecessary(size_t framesToProcess)
{
- ASSERT(context()->isAudioThread());
+ ASSERT(context().isAudioThread());
if (!isInitialized())
return;
@@ -301,7 +292,7 @@ void AudioNode::processIfNecessary(size_t framesToProcess)
// This handles the "fanout" problem where an output is connected to multiple inputs.
// The first time we're called during this time slice we process, but after that we don't want to re-process,
// instead our output(s) will already have the results cached in their bus;
- double currentTime = context()->currentTime();
+ double currentTime = context().currentTime();
if (m_lastProcessingTime != currentTime) {
m_lastProcessingTime = currentTime; // important to first update this time because of feedback loops in the rendering graph
@@ -309,7 +300,7 @@ void AudioNode::processIfNecessary(size_t framesToProcess)
bool silentInputs = inputsAreSilent();
if (!silentInputs)
- m_lastNonSilentTime = (context()->currentSampleFrame() + framesToProcess) / static_cast<double>(m_sampleRate);
+ m_lastNonSilentTime = (context().currentSampleFrame() + framesToProcess) / static_cast<double>(m_sampleRate);
if (silentInputs && propagatesSilence())
silenceOutputs();
@@ -322,9 +313,9 @@ void AudioNode::processIfNecessary(size_t framesToProcess)
void AudioNode::checkNumberOfChannelsForInput(AudioNodeInput* input)
{
- ASSERT(context()->isAudioThread() && context()->isGraphOwner());
+ ASSERT(context().isAudioThread() && context().isGraphOwner());
- for (const std::unique_ptr<AudioNodeInput>& savedInput : m_inputs) {
+ for (auto& savedInput : m_inputs) {
if (input == savedInput.get()) {
input->updateInternalBus();
return;
@@ -336,22 +327,22 @@ void AudioNode::checkNumberOfChannelsForInput(AudioNodeInput* input)
bool AudioNode::propagatesSilence() const
{
- return m_lastNonSilentTime + latencyTime() + tailTime() < context()->currentTime();
+ return m_lastNonSilentTime + latencyTime() + tailTime() < context().currentTime();
}
void AudioNode::pullInputs(size_t framesToProcess)
{
- ASSERT(context()->isAudioThread());
+ ASSERT(context().isAudioThread());
// Process all of the AudioNodes connected to our inputs.
- for (unsigned i = 0; i < m_inputs.size(); ++i)
- input(i)->pull(0, framesToProcess);
+ for (auto& input : m_inputs)
+ input->pull(0, framesToProcess);
}
bool AudioNode::inputsAreSilent()
{
- for (unsigned i = 0; i < m_inputs.size(); ++i) {
- if (!input(i)->bus()->isSilent())
+ for (auto& input : m_inputs) {
+ if (!input->bus()->isSilent())
return false;
}
return true;
@@ -359,25 +350,25 @@ bool AudioNode::inputsAreSilent()
void AudioNode::silenceOutputs()
{
- for (unsigned i = 0; i < m_outputs.size(); ++i)
- output(i)->bus()->zero();
+ for (auto& output : m_outputs)
+ output->bus()->zero();
}
void AudioNode::unsilenceOutputs()
{
- for (unsigned i = 0; i < m_outputs.size(); ++i)
- output(i)->bus()->clearSilentFlag();
+ for (auto& output : m_outputs)
+ output->bus()->clearSilentFlag();
}
void AudioNode::enableOutputsIfNecessary()
{
if (m_isDisabled && m_connectionRefCount > 0) {
ASSERT(isMainThread());
- AudioContext::AutoLocker locker(*context());
+ AudioContext::AutoLocker locker(context());
m_isDisabled = false;
- for (unsigned i = 0; i < m_outputs.size(); ++i)
- output(i)->enable();
+ for (auto& output : m_outputs)
+ output->enable();
}
}
@@ -401,8 +392,8 @@ void AudioNode::disableOutputsIfNecessary()
// longer any active connections.
if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) {
m_isDisabled = true;
- for (unsigned i = 0; i < m_outputs.size(); ++i)
- output(i)->disable();
+ for (auto& output : m_outputs)
+ output->disable();
}
}
}
@@ -438,11 +429,11 @@ void AudioNode::deref(RefType refType)
bool hasLock = false;
bool mustReleaseLock = false;
- if (context()->isAudioThread()) {
+ if (context().isAudioThread()) {
// Real-time audio thread must not contend lock (to avoid glitches).
- hasLock = context()->tryLock(mustReleaseLock);
+ hasLock = context().tryLock(mustReleaseLock);
} else {
- context()->lock(mustReleaseLock);
+ context().lock(mustReleaseLock);
hasLock = true;
}
@@ -451,24 +442,24 @@ void AudioNode::deref(RefType refType)
finishDeref(refType);
if (mustReleaseLock)
- context()->unlock();
+ context().unlock();
} else {
// We were unable to get the lock, so put this in a list to finish up later.
- ASSERT(context()->isAudioThread());
+ ASSERT(context().isAudioThread());
ASSERT(refType == RefTypeConnection);
- context()->addDeferredFinishDeref(this);
+ context().addDeferredFinishDeref(this);
}
// Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here.
// We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive
// because AudioNodes keep a reference to the context.
- if (context()->isAudioThreadFinished())
- context()->deleteMarkedNodes();
+ if (context().isAudioThreadFinished())
+ context().deleteMarkedNodes();
}
void AudioNode::finishDeref(RefType refType)
{
- ASSERT(context()->isGraphOwner());
+ ASSERT(context().isGraphOwner());
switch (refType) {
case RefTypeNormal:
@@ -491,11 +482,11 @@ void AudioNode::finishDeref(RefType refType)
if (!m_normalRefCount) {
if (!m_isMarkedForDeletion) {
// All references are gone - we need to go away.
- for (unsigned i = 0; i < m_outputs.size(); ++i)
- output(i)->disconnectAll(); // This will deref() nodes we're connected to.
+ for (auto& output : m_outputs)
+ output->disconnectAll(); // This will deref() nodes we're connected to.
// Mark for deletion at end of each render quantum or when context shuts down.
- context()->markForDeletion(this);
+ context().markForDeletion(this);
m_isMarkedForDeletion = true;
}
} else if (refType == RefTypeConnection)