Skip to content

Commit

Permalink
Add port audio to relevant packages since both audio, node graph and …
Browse files Browse the repository at this point in the history
…rendering now depend on it.
  • Loading branch information
linuscu committed Sep 2, 2024
1 parent 4f64cfb commit 55aa948
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 94 deletions.
6 changes: 4 additions & 2 deletions packages/audio/include/audio/PortAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ namespace l::audio {

bool OpenStream(int32_t dacBufferFrames, float latency = 0.0f, BufferingMode mode = BufferingMode::DOUBLE_BUFFERING, ChannelMode channel = ChannelMode::STEREO);
bool StartStream();
std::vector<float>& GetWriteBuffer();
bool CanWrite();
void Write(std::vector<float>& out);
void Write();
bool StopStream();
int32_t GetPartTotalSize();
int32_t GetNumFramesPerPart();
Expand All @@ -82,7 +83,8 @@ namespace l::audio {
PaStream* mPaStream;

AudioStreamData mAudioStreamData;
std::vector<float> mBufferInterleaved;
std::vector<float> mOutputBufferInterleaved;
std::vector<float> mWriteBuffer;
};

class AudioManager {
Expand Down
18 changes: 14 additions & 4 deletions packages/audio/source/common/PortAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ namespace l::audio {
mAudioStreamData.mTotalBufferSize = totalNumFrames * mOutputParameters.channelCount;
mAudioStreamData.mNumChannels = static_cast<int32_t>(mOutputParameters.channelCount);

mBufferInterleaved.resize(mAudioStreamData.mTotalBufferSize);
mAudioStreamData.mBuffer = mBufferInterleaved.data();
mOutputBufferInterleaved.resize(mAudioStreamData.mTotalBufferSize);
mAudioStreamData.mBuffer = mOutputBufferInterleaved.data();

auto err = Pa_OpenStream(
&mPaStream,
Expand All @@ -132,17 +132,27 @@ namespace l::audio {
LOG(LogError) << "Failed to start stream: " << err;
return false;
}

auto bufferSize = GetPartTotalSize();
if (mWriteBuffer.size() != bufferSize) {
mWriteBuffer.resize(bufferSize);
}

return true;
}

std::vector<float>& AudioStream::GetWriteBuffer() {
return mWriteBuffer;
}

bool AudioStream::CanWrite() {
return mAudioStreamData.mDacWriteReady.try_acquire();
}

void AudioStream::Write(std::vector<float>& out) {
void AudioStream::Write() {
float* buffer = mAudioStreamData.GetCurrentBufferPosition();

float* outPtr = out.data();
float* outPtr = mWriteBuffer.data();
for (int i = 0; i < mAudioStreamData.mDacFramesPerBufferPart; i++) {
*buffer++ = *outPtr++;
*buffer++ = *outPtr++;
Expand Down
5 changes: 2 additions & 3 deletions packages/audio/tests/common/PortAudioTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ TEST(PortAudio, Setup) {
return 0;
}

std::vector<float> buffer;
float sinePhase = 0.0f;
float freq = 300.0f;
float fMod = 1.0f;
Expand All @@ -30,7 +29,7 @@ TEST(PortAudio, Setup) {

float pModPhase = 0.0f;

buffer.resize(stream->GetPartTotalSize());
auto& buffer = stream->GetWriteBuffer();

float deltaTime = 1.0f / static_cast<float>(stream->GetSampleRate());
int32_t loops = 10;
Expand All @@ -52,7 +51,7 @@ TEST(PortAudio, Setup) {
buffer.at(2 * i + 0) = 0.5f * sinf(3.141529f * (mPhase + phaseMod));
buffer.at(2 * i + 1) = 0.5f * sinf(3.141529f * (mPhase + phaseMod));
}
stream->Write(buffer);
stream->Write();
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} while (loops-- > 0);
Expand Down
2 changes: 1 addition & 1 deletion packages/nodegraph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ set(deps
audio
)

bs_generate_package(nodegraph "tier1" "${deps}" "")
bs_generate_package(nodegraph "tier1" "${deps}" "PortAudio")
23 changes: 14 additions & 9 deletions packages/nodegraph/include/nodegraph/NodeGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace l::nodegraph {

void ClearProcessFlags();
virtual void ProcessSubGraph(bool recomputeSubGraphCache = true);
virtual void Tick(float time);
virtual void Tick(float time, float elapsed);

virtual void SetNumInputs(int8_t numInputs);
virtual void SetNumOutputs(int8_t outputCount);
Expand Down Expand Up @@ -129,8 +129,8 @@ namespace l::nodegraph {

virtual ~NodeGraphOp() = default;
virtual void Reset() {}
virtual void ProcessSubGraph(std::vector<NodeGraphInput>& mInputs, std::vector<NodeGraphOutput>& outputs) = 0;
virtual void Tick(float) {}
virtual void ProcessSubGraph(std::vector<NodeGraphInput>&, std::vector<NodeGraphOutput>&) {};
virtual void Tick(float, float) {}

virtual void SetNumInputs(int8_t numInputs);
virtual void SetNumOutputs(int8_t numOutputs);
Expand Down Expand Up @@ -211,9 +211,9 @@ namespace l::nodegraph {
mOperation.ProcessSubGraph(mInputs, mOutputs);
}

virtual void Tick(float time) override {
NodeGraphBase::Tick(time);
mOperation.Tick(time);
virtual void Tick(float time, float elapsed) override {
NodeGraphBase::Tick(time, elapsed);
mOperation.Tick(time, elapsed);
}

virtual std::string_view GetInputName(int8_t inputChannel) {
Expand Down Expand Up @@ -273,19 +273,24 @@ namespace l::nodegraph {
bool RemoveNode(int32_t id);

template<class T, class = std::enable_if_t<std::is_base_of_v<NodeGraphOp, T>>, class... Params>
l::nodegraph::NodeGraphBase* NewNode(Params&&... params) {
l::nodegraph::NodeGraphBase* NewNode(bool outputNode, Params&&... params) {
mNodes.push_back(std::make_unique<l::nodegraph::NodeGraph<T, Params...>>(std::forward<Params>(params)...));
return mNodes.back().get();
auto nodePtr = mNodes.back().get();
if (outputNode) {
mOutputNodes.push_back(nodePtr);
}
return nodePtr;
}

void ClearProcessFlags();
void ProcessSubGraph(bool recomputeSubGraphCache = true);
void Tick(float time);
void Tick(float time, float elapsed);
protected:
NodeGraph<GraphDataCopy> mInputNode;
NodeGraph<GraphDataCopy> mOutputNode;

std::vector<std::unique_ptr<NodeGraphBase>> mNodes;
std::vector<NodeGraphBase*> mOutputNodes;
};

}
Expand Down
61 changes: 53 additions & 8 deletions packages/nodegraph/include/nodegraph/NodeGraphOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "logging/LoggingAll.h"
#include "hid/KeyboardPiano.h"
#include "audio/PortAudio.h"

#include <string>
#include <vector>
Expand Down Expand Up @@ -42,8 +43,8 @@ namespace l::nodegraph {
}

virtual ~GraphSourceConstants() = default;
void ProcessSubGraph(std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
virtual void Tick(float) override;
virtual void ProcessSubGraph(std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
virtual void Tick(float, float) override;

std::string_view GetName() override;
bool IsDataVisible(int8_t) override;
Expand All @@ -55,6 +56,27 @@ namespace l::nodegraph {
float mMin = 0.0f;
};

class GraphSourceTime : public NodeGraphOp {
public:
GraphSourceTime(NodeGraphBase* node) :
NodeGraphOp(node, 0, 2, 0)
{}

std::string defaultOutStrings[2] = { "Audio Time", "Frame Time"};

virtual ~GraphSourceTime() = default;
virtual void ProcessSubGraph(std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
virtual void Tick(float, float) override;

void Reset() override;
std::string_view GetOutputName(int8_t outputChannel);
std::string_view GetName() override;

protected:
float mAudioTime = 0.0f;
float mFrameTime = 0.0f;
};

class GraphSourceSine : public NodeGraphOp {
public:
GraphSourceSine(NodeGraphBase* node) :
Expand Down Expand Up @@ -91,7 +113,7 @@ namespace l::nodegraph {

virtual ~GraphSourceKeyboard() = default;
void ProcessSubGraph(std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
void Tick(float time) override;
void Tick(float time, float elapsed) override;
void Reset() override;
virtual std::string_view GetOutputName(int8_t outputChannel) override;
virtual std::string_view GetName() override;
Expand Down Expand Up @@ -247,23 +269,46 @@ namespace l::nodegraph {
float mState1 = 0.0f;
};

class GraphGraphicDisplay : public NodeGraphOp {
class GraphOutputDebug : public NodeGraphOp {
public:
GraphGraphicDisplay(NodeGraphBase* node, int32_t numValueDisplays) :
GraphOutputDebug(NodeGraphBase* node, int32_t numValueDisplays) :
NodeGraphOp(node, numValueDisplays, 0, 0)
{}

bool IsDataVisible(int8_t) override {
return true;
}

virtual ~GraphGraphicDisplay() = default;
virtual ~GraphOutputDebug() = default;

std::string_view GetName() override {
return "Debug";
}
};

class GraphOutputSpeaker : public NodeGraphOp {
public:
GraphOutputSpeaker(NodeGraphBase* node, l::audio::AudioStream* stream = nullptr) :
NodeGraphOp(node, 2, 0, 0),
mAudioStream(stream),
mCurrentStereoPosition(0)
{}

bool IsDataVisible(int8_t) override {
return true;
}

virtual ~GraphOutputSpeaker() = default;
void ProcessSubGraph(std::vector<NodeGraphInput>& inputs, std::vector<NodeGraphOutput>& outputs) override;
virtual void Tick(float time) override;
virtual void Tick(float time, float elapsed) override;

std::string_view GetName() override {
return "Display";
return "Speaker";
}

protected:
l::audio::AudioStream* mAudioStream;
int32_t mCurrentStereoPosition;
};
}

10 changes: 7 additions & 3 deletions packages/nodegraph/include/nodegraph/NodeGraphSchema.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ namespace l::nodegraph {
RegisterNodeType("Source", 2, "Value [0,100]");
RegisterNodeType("Source", 3, "Value [-inf,inf]");
RegisterNodeType("Source", 4, "Keyboard");
RegisterNodeType("Source", 5, "Sine");
RegisterNodeType("Source", 5, "Time");
RegisterNodeType("Source", 6, "Sine");
RegisterNodeType("Numeric", 50, "Add");
RegisterNodeType("Numeric", 51, "Subtract");
RegisterNodeType("Numeric", 52, "Negate");
Expand All @@ -47,13 +48,15 @@ namespace l::nodegraph {
RegisterNodeType("Logic", 101, "Or");
RegisterNodeType("Logic", 102, "Xor");
RegisterNodeType("Filter", 150, "Lowpass Filter");
RegisterNodeType("Graphic", 200, "Display");
RegisterNodeType("Output", 200, "Value Debug");
RegisterNodeType("Output", 201, "Speaker");
}

~NodeGraphSchema() = default;

void SetCustomCreator(std::function<CustomCreateFunctionType> customCreator);
void SetKeyState(l::hid::KeyState* keyState);
void SetAudioOutput(l::audio::AudioStream* audioStream);

int32_t NewNode(int32_t typeId);
bool RemoveNode(int32_t nodeId);
Expand All @@ -67,12 +70,13 @@ namespace l::nodegraph {
void ForEachNodeType(std::function<void(std::string_view, const std::vector<UINodeDesc>&)> cb) const;
void RegisterNodeType(const std::string& typeGroup, int32_t uniqueTypeId, std::string_view typeName);
void ProcessSubGraph();
void Tick(float time);
void Tick(float time, float elapsed);
protected:
NodeGraphGroup mMainNodeGraph;

std::function<CustomCreateFunctionType> mCreateCustomNode;
l::hid::KeyState* mKeyState;
l::audio::AudioStream* mAudioOutput;

std::map<std::string, std::vector<UINodeDesc>> mRegisteredNodeTypes;
};
Expand Down
24 changes: 16 additions & 8 deletions packages/nodegraph/source/common/NodeGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ namespace l::nodegraph {
mProcessUpdateHasRun = true;
}

void NodeGraphBase::Tick(float time) {
void NodeGraphBase::Tick(float time, float elapsed) {
for (auto& link : mInputs) {
if (link.mInputType == InputType::INPUT_NODE && link.mInput.mInputNode != nullptr) {
link.mInput.mInputNode->Tick(time);
link.mInput.mInputNode->Tick(time, elapsed);
}
}
}
Expand Down Expand Up @@ -371,6 +371,12 @@ namespace l::nodegraph {
sourceCount++;
}
}
std::erase_if(mOutputNodes, [&](NodeGraphBase* nodePtr) {
if (nodePtr == node) {
return true;
}
return false;
});
auto count = std::erase_if(mNodes, [&](const std::unique_ptr<NodeGraphBase>& node) {
if (node->GetId() == id) {
return true;
Expand All @@ -384,16 +390,18 @@ namespace l::nodegraph {
mOutputNode.ClearProcessFlags();
}

void NodeGraphGroup::ProcessSubGraph(bool recomputeSubGraphCache) {
if (recomputeSubGraphCache) {
mOutputNode.ClearProcessFlags();
void NodeGraphGroup::ProcessSubGraph(bool) {
for (auto& it : mOutputNodes) {
it->ClearProcessFlags();
}
for (auto& it : mOutputNodes) {
it->ProcessSubGraph(false);
}
mOutputNode.ProcessSubGraph(false);
}

void NodeGraphGroup::Tick(float time) {
void NodeGraphGroup::Tick(float time, float elapsed) {
for (auto& it : mNodes) {
it->Tick(time);
it->Tick(time, elapsed);
}
}
}
Loading

0 comments on commit 55aa948

Please sign in to comment.