finished audio effects support in audio renderer
Working structure implemented in previous commit into the audio renderer is complete in this commit.
This commit is contained in:
@@ -39,19 +39,19 @@ QString PanNode::Description() const
|
|||||||
return tr("Adjust the stereo panning of an audio source.");
|
return tr("Adjust the stereo panning of an audio source.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PanNode::ProcessesSamples() const
|
NodeInput *PanNode::ProcessesSamplesFrom() const
|
||||||
{
|
{
|
||||||
return true;
|
return samples_input_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PanNode::ProcessSamples(const NodeValueDatabase &values, const AudioRenderingParams ¶ms, const float *input, float *output, int index) const
|
void PanNode::ProcessSamples(const NodeValueDatabase *values, const AudioRenderingParams ¶ms, const float *input, float *output, int index) const
|
||||||
{
|
{
|
||||||
if (params.channel_count() != 2) {
|
if (params.channel_count() != 2) {
|
||||||
// This node currently only works for stereo audio
|
// This node currently only works for stereo audio
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pan_val = values[panning_input_].Get(NodeParam::kFloat).toFloat();
|
float pan_val = (*values)[panning_input_].Get(NodeParam::kFloat).toFloat();
|
||||||
|
|
||||||
if (index%2 == 0) {
|
if (index%2 == 0) {
|
||||||
// Sample is left channel
|
// Sample is left channel
|
||||||
@@ -65,3 +65,9 @@ void PanNode::ProcessSamples(const NodeValueDatabase &values, const AudioRenderi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PanNode::Retranslate()
|
||||||
|
{
|
||||||
|
samples_input_->set_name(tr("Samples"));
|
||||||
|
panning_input_->set_name(tr("Pan"));
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ public:
|
|||||||
virtual QString Category() const override;
|
virtual QString Category() const override;
|
||||||
virtual QString Description() const override;
|
virtual QString Description() const override;
|
||||||
|
|
||||||
virtual bool ProcessesSamples() const override;
|
virtual NodeInput* ProcessesSamplesFrom() const override;
|
||||||
virtual void ProcessSamples(const NodeValueDatabase& values, const AudioRenderingParams& params, const float* input, float* output, int index) const override;
|
virtual void ProcessSamples(const NodeValueDatabase* values, const AudioRenderingParams& params, const float* input, float* output, int index) const override;
|
||||||
|
|
||||||
|
virtual void Retranslate() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeInput* samples_input_;
|
NodeInput* samples_input_;
|
||||||
|
|||||||
@@ -39,14 +39,25 @@ QString VolumeNode::Description() const
|
|||||||
return tr("Adjusts the volume of an audio source.");
|
return tr("Adjusts the volume of an audio source.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VolumeNode::ProcessesSamples() const
|
NodeInput *VolumeNode::ProcessesSamplesFrom() const
|
||||||
{
|
{
|
||||||
return true;
|
return samples_input_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeNode::ProcessSamples(const NodeValueDatabase& values, const AudioRenderingParams& params, const float* input, float* output, int index) const
|
void VolumeNode::ProcessSamples(const NodeValueDatabase *values, const AudioRenderingParams& params, const float* input, float* output, int index) const
|
||||||
{
|
{
|
||||||
float volume_val = values[volume_input_].Get(NodeParam::kFloat).toFloat();
|
float volume_val = (*values)[volume_input_].Get(NodeParam::kFloat).toFloat();
|
||||||
|
|
||||||
output[index] = input[index] * volume_val;
|
output[index] = input[index] * volume_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VolumeNode::Retranslate()
|
||||||
|
{
|
||||||
|
samples_input_->set_name(tr("Samples"));
|
||||||
|
volume_input_->set_name(tr("Volume"));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeInput *VolumeNode::samples_input() const
|
||||||
|
{
|
||||||
|
return samples_input_;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ public:
|
|||||||
virtual QString Category() const override;
|
virtual QString Category() const override;
|
||||||
virtual QString Description() const override;
|
virtual QString Description() const override;
|
||||||
|
|
||||||
virtual bool ProcessesSamples() const override;
|
virtual NodeInput* ProcessesSamplesFrom() const override;
|
||||||
virtual void ProcessSamples(const NodeValueDatabase& values, const AudioRenderingParams& params, const float* input, float* output, int index) const override;
|
virtual void ProcessSamples(const NodeValueDatabase* values, const AudioRenderingParams& params, const float* input, float* output, int index) const override;
|
||||||
|
|
||||||
|
virtual void Retranslate() override;
|
||||||
|
|
||||||
|
NodeInput* samples_input() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeInput* samples_input_;
|
NodeInput* samples_input_;
|
||||||
|
|||||||
+3
-3
@@ -390,12 +390,12 @@ NodeInput *Node::AcceleratedCodeIterativeInput() const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Node::ProcessesSamples() const
|
NodeInput* Node::ProcessesSamplesFrom() const
|
||||||
{
|
{
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ProcessSamples(const NodeValueDatabase &values, const AudioRenderingParams ¶ms, const float *input, float *output, int index) const
|
void Node::ProcessSamples(const NodeValueDatabase *values, const AudioRenderingParams ¶ms, const float *input, float *output, int index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(values)
|
Q_UNUSED(values)
|
||||||
Q_UNUSED(params)
|
Q_UNUSED(params)
|
||||||
|
|||||||
+2
-2
@@ -160,12 +160,12 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Return whether this node processes samples or not
|
* @brief Return whether this node processes samples or not
|
||||||
*/
|
*/
|
||||||
virtual bool ProcessesSamples() const;
|
virtual NodeInput* ProcessesSamplesFrom() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief If ProcessesSamples() is true, this is the function that will process them.
|
* @brief If ProcessesSamples() is true, this is the function that will process them.
|
||||||
*/
|
*/
|
||||||
virtual void ProcessSamples(const NodeValueDatabase& values, const AudioRenderingParams& params, const float* input, float* output, int index) const;
|
virtual void ProcessSamples(const NodeValueDatabase *values, const AudioRenderingParams& params, const float* input, float* output, int index) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the parameter with the specified ID (or nullptr if it doesn't exist)
|
* @brief Returns the parameter with the specified ID (or nullptr if it doesn't exist)
|
||||||
|
|||||||
@@ -11,3 +11,35 @@ void AudioWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
|||||||
|
|
||||||
table->Push(NodeParam::kSamples, frame->ToByteArray());
|
table->Push(NodeParam::kSamples, frame->ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase *input_params, NodeValueTable *output_params)
|
||||||
|
{
|
||||||
|
// Check if node processes samples
|
||||||
|
if (!node->ProcessesSamplesFrom()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the sample buffer in the table
|
||||||
|
QVariant samples_var = (*input_params)[node->ProcessesSamplesFrom()].Get(NodeParam::kSamples);
|
||||||
|
|
||||||
|
// If there isn't one, there's nothing to do
|
||||||
|
if (samples_var.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray input_buffer = samples_var.toByteArray();
|
||||||
|
QByteArray output_buffer(input_buffer.size(), 0);
|
||||||
|
|
||||||
|
int sample_count = input_buffer.size() / audio_params().bytes_per_sample_per_channel();
|
||||||
|
|
||||||
|
// FIXME: Hardcoded float sample format
|
||||||
|
for (int i=0;i<sample_count;i++) {
|
||||||
|
node->ProcessSamples(input_params,
|
||||||
|
audio_params(),
|
||||||
|
reinterpret_cast<const float*>(input_buffer.constData()),
|
||||||
|
reinterpret_cast<float*>(output_buffer.data()),
|
||||||
|
i);
|
||||||
|
}
|
||||||
|
|
||||||
|
output_params->Push(NodeParam::kSamples, output_buffer);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable* table) override;
|
virtual void FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable* table) override;
|
||||||
|
|
||||||
|
virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase *input_params, NodeValueTable* output_params) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,3 +90,8 @@ NodeValueTable AudioRenderWorker::RenderBlock(const TrackOutput *track, const Ti
|
|||||||
|
|
||||||
return merged_table;
|
return merged_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AudioRenderingParams &AudioRenderWorker::audio_params() const
|
||||||
|
{
|
||||||
|
return audio_params_;
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ protected:
|
|||||||
|
|
||||||
virtual NodeValueTable RenderBlock(const TrackOutput *track, const TimeRange& range) override;
|
virtual NodeValueTable RenderBlock(const TrackOutput *track, const TimeRange& range) override;
|
||||||
|
|
||||||
|
const AudioRenderingParams& audio_params() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioRenderingParams audio_params_;
|
AudioRenderingParams audio_params_;
|
||||||
|
|
||||||
|
|||||||
@@ -42,12 +42,6 @@ NodeValueTable RenderWorker::RenderInternal(const NodeDependency &path)
|
|||||||
return ProcessNode(path);
|
return ProcessNode(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderWorker::OutputIsAccelerated(Node *output)
|
|
||||||
{
|
|
||||||
Q_UNUSED(output)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase *input_params, NodeValueTable* output_params)
|
void RenderWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase *input_params, NodeValueTable* output_params)
|
||||||
{
|
{
|
||||||
Q_UNUSED(node)
|
Q_UNUSED(node)
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ protected:
|
|||||||
|
|
||||||
virtual NodeValueTable RenderInternal(const NodeDependency& path);
|
virtual NodeValueTable RenderInternal(const NodeDependency& path);
|
||||||
|
|
||||||
virtual bool OutputIsAccelerated(Node *output);
|
|
||||||
|
|
||||||
virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase *input_params, NodeValueTable* output_params);
|
virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase *input_params, NodeValueTable* output_params);
|
||||||
|
|
||||||
StreamPtr ResolveStreamFromInput(NodeInput* input);
|
StreamPtr ResolveStreamFromInput(NodeInput* input);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "common/qtversionabstraction.h"
|
#include "common/qtversionabstraction.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "node/audio/volume/volume.h"
|
||||||
#include "node/distort/transform/transform.h"
|
#include "node/distort/transform/transform.h"
|
||||||
#include "node/input/media/audio/audio.h"
|
#include "node/input/media/audio/audio.h"
|
||||||
#include "node/input/media/video/video.h"
|
#include "node/input/media/video/video.h"
|
||||||
@@ -254,7 +255,12 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event)
|
|||||||
AudioInput* audio_input = new AudioInput();
|
AudioInput* audio_input = new AudioInput();
|
||||||
audio_input->SetFootage(footage_stream);
|
audio_input->SetFootage(footage_stream);
|
||||||
new NodeAddCommand(dst_graph, audio_input, command);
|
new NodeAddCommand(dst_graph, audio_input, command);
|
||||||
new NodeEdgeAddCommand(audio_input->output(), clip->texture_input(), command);
|
|
||||||
|
VolumeNode* volume_node = new VolumeNode();
|
||||||
|
new NodeAddCommand(dst_graph, volume_node, command);
|
||||||
|
|
||||||
|
new NodeEdgeAddCommand(audio_input->output(), volume_node->samples_input(), command);
|
||||||
|
new NodeEdgeAddCommand(volume_node->output(), clip->texture_input(), command);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user