File Node.h¶
File List > Amplitude > Mixer > Node.h
Go to the documentation of this file
// Copyright (c) 2024-present Sparky Studios. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef _AM_MIXER_NODE_H
#define _AM_MIXER_NODE_H
#include <SparkyStudios/Audio/Amplitude/Core/AudioBuffer.h>
#include <SparkyStudios/Audio/Amplitude/Core/Common.h>
#include <SparkyStudios/Audio/Amplitude/DSP/Filter.h>
namespace SparkyStudios::Audio::Amplitude
{
class AmplimixLayer;
class PipelineInstance;
class AM_API_PUBLIC NodeInstance
{
friend class PipelineInstance;
public:
virtual void Initialize(AmObjectID id, const AmplimixLayer* layer, const PipelineInstance* pipeline, AmSize paramCount);
virtual ~NodeInstance() = default;
[[nodiscard]] AmObjectID GetId() const;
[[nodiscard]] const AmplimixLayer* GetLayer() const;
virtual void Reset() = 0;
virtual AmReal32 GetParameter(AmSize index);
virtual void SetParameter(AmSize index, AmReal32 value);
virtual void Configure(AmUInt64 frameCount, AmUInt16 channelCount);
[[nodiscard]] virtual AmUInt64 GetOutputFrameCount() const;
[[nodiscard]] virtual AmUInt16 GetOutputChannelCount() const;
[[nodiscard]] virtual bool ShouldSkip() const;
protected:
AmUInt64 m_inputFrameCount = 0;
AmUInt16 m_inputChannelCount = 0;
AmObjectID m_id;
const AmplimixLayer* m_layer;
const PipelineInstance* m_pipeline;
AmUInt32 m_numParamsChanged;
std::vector<AmReal32> m_parameters;
};
class AM_API_PUBLIC ConsumerNodeInstance
{
public:
virtual ~ConsumerNodeInstance() = default;
virtual void Consume() = 0;
virtual void Connect(AmObjectID provider) = 0;
};
class AM_API_PUBLIC ProviderNodeInstance
{
public:
virtual ~ProviderNodeInstance() = default;
virtual const AudioBuffer* Provide() = 0;
};
class AM_API_PUBLIC ProcessorNodeInstance
: public NodeInstance
, public ConsumerNodeInstance
, public ProviderNodeInstance
{
public:
explicit ProcessorNodeInstance(bool processOnEmptyBuffer = false);
~ProcessorNodeInstance() override = default;
virtual const AudioBuffer* Process(const AudioBuffer* input) = 0;
void Consume() final;
void Connect(AmObjectID provider) final;
const AudioBuffer* Provide() final;
void Reset() override;
void Configure(AmUInt64 frameCount, AmUInt16 channelCount) override;
[[nodiscard]] AM_INLINE AmObjectID GetProvider() const
{
return m_provider;
}
protected:
AmObjectID m_provider;
AudioBuffer _output;
private:
const AudioBuffer* _processingBuffer;
const AudioBuffer* _lastOutputBuffer;
bool _processOnEmptyInputBuffer;
ProviderNodeInstance* _cachedProvider;
};
class AM_API_PUBLIC MixerNodeInstance
: public NodeInstance
, public ConsumerNodeInstance
, public ProviderNodeInstance
{
public:
MixerNodeInstance();
~MixerNodeInstance() override = default;
void Consume() final;
void Connect(AmObjectID provider) final;
void Connect(const std::vector<AmObjectID>& providers);
const AudioBuffer* Provide() final;
void Reset() override;
void Configure(AmUInt64 frameCount, AmUInt16 channelCount) override;
[[nodiscard]] AM_INLINE const std::vector<AmObjectID>& GetProviders() const
{
return m_providers;
}
protected:
std::vector<AmObjectID> m_providers;
AudioBuffer _mixBuffer;
private:
std::vector<const AudioBuffer*> _processingBuffers;
bool _processed;
std::vector<ProviderNodeInstance*> _cachedProviders;
};
class AM_API_PUBLIC InputNodeInstance
: public NodeInstance
, public ProviderNodeInstance
{
friend class PipelineInstance;
public:
InputNodeInstance();
~InputNodeInstance() override = default;
void SetInput(AudioBuffer* buffer);
const AudioBuffer* Provide() override;
void Reset() override;
private:
AudioBuffer* _buffer;
std::shared_ptr<FilterInstance> _filter;
};
class AM_API_PUBLIC OutputNodeInstance
: public NodeInstance
, public ConsumerNodeInstance
{
friend class PipelineInstance;
public:
OutputNodeInstance();
~OutputNodeInstance() override = default;
void SetOutput(AudioBuffer* buffer);
void Consume() override;
void Connect(AmObjectID provider) override;
void Reset() override;
private:
AmObjectID _provider;
AudioBuffer* _buffer;
ProviderNodeInstance* _cachedProvider;
};
class AM_API_PUBLIC Node
{
public:
explicit Node(AmString name);
virtual ~Node();
virtual std::shared_ptr<NodeInstance> CreateInstance() const = 0;
[[nodiscard]] const AmString& GetName() const;
[[nodiscard]] virtual bool CanConsume() const = 0;
[[nodiscard]] virtual bool CanProduce() const = 0;
[[nodiscard]] virtual AmSize GetMaxInputCount() const = 0;
[[nodiscard]] virtual AmSize GetMinInputCount() const = 0;
[[nodiscard]] virtual AmSize GetParameterCount() const;
[[nodiscard]] virtual AmString GetParameterName(AmSize index) const;
[[nodiscard]] virtual eParameterType GetParameterType(AmSize index) const;
[[nodiscard]] virtual AmReal32 GetParameterMax(AmSize index) const;
[[nodiscard]] virtual AmReal32 GetParameterMin(AmSize index) const;
static void Register(std::shared_ptr<Node> node);
static void Unregister(std::shared_ptr<const Node> node);
static std::shared_ptr<Node> Find(const AmString& name);
static std::shared_ptr<NodeInstance> Construct(const AmString& name);
static void LockRegistry();
static void UnlockRegistry();
static const std::map<AmString, std::shared_ptr<Node>>& GetRegistry();
protected:
AmString m_name;
};
} // namespace SparkyStudios::Audio::Amplitude
#endif // _AM_MIXER_NODE_H