#pragma once
#include "AudioBus.h"
#include "ChannelCountMode.h"
#include "ChannelInterpretation.h"
#include "EventTarget.h"
#include "ExceptionOr.h"
#include <wtf/Forward.h>
#include <wtf/LoggerHelper.h>
#include <wtf/Variant.h>
#define DEBUG_AUDIONODE_REFERENCES 0
namespace WebCore {
class AudioNodeInput;
struct AudioNodeOptions;
class AudioNodeOutput;
class AudioParam;
class BaseAudioContext;
class WebKitAudioContext;
class AudioNode
: public EventTargetWithInlineData
#if !RELEASE_LOG_DISABLED
, private LoggerHelper
#endif
{
WTF_MAKE_NONCOPYABLE(AudioNode);
WTF_MAKE_ISO_ALLOCATED(AudioNode);
public:
enum { ProcessingSizeInFrames = 128 };
AudioNode(BaseAudioContext&, float sampleRate);
AudioNode(BaseAudioContext&);
virtual ~AudioNode();
BaseAudioContext& context() { return m_context.get(); }
const BaseAudioContext& context() const { return m_context.get(); }
Variant<RefPtr<BaseAudioContext>, RefPtr<WebKitAudioContext>> contextForBindings() const;
enum NodeType {
NodeTypeUnknown,
NodeTypeDestination,
NodeTypeOscillator,
NodeTypeAudioBufferSource,
NodeTypeMediaElementAudioSource,
NodeTypeMediaStreamAudioDestination,
NodeTypeMediaStreamAudioSource,
NodeTypeJavaScript,
NodeTypeBiquadFilter,
NodeTypePanner,
NodeTypeConvolver,
NodeTypeDelay,
NodeTypeGain,
NodeTypeChannelSplitter,
NodeTypeChannelMerger,
NodeTypeAnalyser,
NodeTypeDynamicsCompressor,
NodeTypeWaveShaper,
NodeTypeBasicInspector,
NodeTypeEnd
};
NodeType nodeType() const { return m_nodeType; }
void setNodeType(NodeType);
enum RefType { RefTypeNormal, RefTypeConnection };
void ref(RefType refType = RefTypeNormal);
void deref(RefType refType = RefTypeNormal);
void finishDeref(RefType refType);
virtual void didBecomeMarkedForDeletion() { }
virtual void process(size_t framesToProcess) = 0;
virtual void reset() = 0;
virtual void initialize();
virtual void uninitialize();
bool isInitialized() const { return m_isInitialized; }
void lazyInitialize();
unsigned numberOfInputs() const { return m_inputs.size(); }
unsigned numberOfOutputs() const { return m_outputs.size(); }
AudioNodeInput* input(unsigned);
AudioNodeOutput* output(unsigned);
virtual ExceptionOr<void> connect(AudioNode&, unsigned outputIndex, unsigned inputIndex);
ExceptionOr<void> connect(AudioParam&, unsigned outputIndex);
virtual ExceptionOr<void> disconnect(unsigned outputIndex);
virtual float sampleRate() const { return m_sampleRate; }
void processIfNecessary(size_t framesToProcess);
virtual void checkNumberOfChannelsForInput(AudioNodeInput*);
#if DEBUG_AUDIONODE_REFERENCES
static void printNodeCounts();
#endif
bool isMarkedForDeletion() const { return m_isMarkedForDeletion; }
virtual double tailTime() const = 0;
virtual double latencyTime() const = 0;
virtual bool propagatesSilence() const;
bool inputsAreSilent();
void silenceOutputs();
void enableOutputsIfNecessary();
void disableOutputsIfNecessary();
unsigned channelCount() const { return m_channelCount; }
virtual ExceptionOr<void> setChannelCount(unsigned);
ChannelCountMode channelCountMode() const { return m_channelCountMode; }
virtual ExceptionOr<void> setChannelCountMode(ChannelCountMode);
ChannelInterpretation channelInterpretation() const { return m_channelInterpretation; }
virtual ExceptionOr<void> setChannelInterpretation(ChannelInterpretation);
protected:
void addInput(std::unique_ptr<AudioNodeInput>);
void addOutput(std::unique_ptr<AudioNodeOutput>);
virtual void pullInputs(size_t framesToProcess);
void updateChannelsForInputs();
#if !RELEASE_LOG_DISABLED
const Logger& logger() const final { return m_logger.get(); }
const void* logIdentifier() const final { return m_logIdentifier; }
const char* logClassName() const final { return "AudioNode"; }
WTFLogChannel& logChannel() const final;
#endif
private:
EventTargetInterface eventTargetInterface() const override;
ScriptExecutionContext* scriptExecutionContext() const final;
volatile bool m_isInitialized { false };
NodeType m_nodeType { NodeTypeUnknown };
Ref<BaseAudioContext> m_context;
float m_sampleRate;
Vector<std::unique_ptr<AudioNodeInput>> m_inputs;
Vector<std::unique_ptr<AudioNodeOutput>> m_outputs;
double m_lastProcessingTime { -1 };
double m_lastNonSilentTime { -1 };
std::atomic<int> m_normalRefCount { 1 };
std::atomic<int> m_connectionRefCount { 0 };
bool m_isMarkedForDeletion { false };
bool m_isDisabled { false };
#if DEBUG_AUDIONODE_REFERENCES
static bool s_isNodeCountInitialized;
static int s_nodeCount[NodeTypeEnd];
#endif
void refEventTarget() override { ref(); }
void derefEventTarget() override { deref(); }
#if !RELEASE_LOG_DISABLED
mutable Ref<const Logger> m_logger;
const void* m_logIdentifier;
#endif
protected:
unsigned m_channelCount;
ChannelCountMode m_channelCountMode;
ChannelInterpretation m_channelInterpretation;
};
String convertEnumerationToString(AudioNode::NodeType);
}
namespace WTF {
template<> struct LogArgument<WebCore::AudioNode::NodeType> {
static String toString(WebCore::AudioNode::NodeType type) { return convertEnumerationToString(type); }
};
}