Skip to content

Commit

Permalink
Add AudioNode interface and implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sakertooth committed Jan 18, 2024
1 parent d945ac1 commit 008546d
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
84 changes: 84 additions & 0 deletions include/AudioNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* AudioSoure.h
*
* Copyright (c) 2024 saker <[email protected]>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#ifndef LMMS_AUDIO_NODE_H
#define LMMS_AUDIO_NODE_H

#include <optional>
#include <vector>

#include "lmms_basics.h"
#include "lmms_export.h"

namespace lmms {

class LMMS_EXPORT AudioNode
{
public:
struct Buffer
{
const sampleFrame* buffer;
size_t size;
};

class Processor
{
public:
//! Creates a `Processor` for node `currentNode`.
Processor(AudioNode* currentNode);

//! First runs any dependencies for this node, then runs itself.
auto run() -> std::optional<Buffer>;

//! Add another node as a dependency to this node.
void addDependency(AudioNode* node);

//! Remove another node as a dependency to this node.
void removeDependency(AudioNode* node);

//! Add a buffer as input to this node.
void addInput(Buffer input);

//! Take all inputs from this node.
auto inputs() -> std::vector<Buffer>;

private:
std::vector<AudioNode*> m_dependencies;
std::vector<Buffer> m_inputs;
AudioNode* m_currentNode;
};

virtual ~AudioNode() = default;

//! Returns the processor for this node.
virtual auto processor() -> Processor& = 0;

private:
//! Internal processing meant to be implemented by subclasses.
virtual auto process() -> std::optional<Buffer> = 0;
friend class Processor;
};
} // namespace lmms

#endif // LMMS_AUDIO_NODE_H
69 changes: 69 additions & 0 deletions src/core/AudioNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* AudioSoure.cpp
*
* Copyright (c) 2024 saker <[email protected]>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#include "AudioNode.h"

#include <algorithm>

namespace lmms {
AudioNode::Processor::Processor(AudioNode* currentNode)
: m_currentNode(currentNode)
{
}

auto AudioNode::Processor::run() -> std::optional<Buffer>
{
for (auto& dependency : m_dependencies)
{
auto buffer = dependency->processor().run();
if (buffer) { m_currentNode->processor().addInput(buffer.value()); }
}
return m_currentNode->process();
}

void AudioNode::Processor::addInput(Buffer input)
{
m_inputs.push_back(input);
}

auto AudioNode::Processor::inputs() -> std::vector<Buffer>
{
const auto inputs = m_inputs;
m_inputs.clear();
return inputs;
}

void AudioNode::Processor::addDependency(AudioNode* node)
{
if (std::find(m_dependencies.begin(), m_dependencies.end(), node) != m_dependencies.end()) { return; }
m_dependencies.push_back(node);
}

void AudioNode::Processor::removeDependency(AudioNode* node)
{
if (std::find(m_dependencies.begin(), m_dependencies.end(), node) == m_dependencies.end()) { return; }
m_dependencies.erase(std::remove(m_dependencies.begin(), m_dependencies.end(), node), m_dependencies.end());
}

} // namespace lmms
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(LMMS_SRCS
core/AudioEngine.cpp
core/AudioEngineProfiler.cpp
core/AudioEngineWorkerThread.cpp
core/AudioNode.cpp
core/AudioResampler.cpp
core/AutomatableModel.cpp
core/AutomationClip.cpp
Expand Down

0 comments on commit 008546d

Please sign in to comment.