rewrote renderers where necessary for new node structure

Largely conforming renderers to new NodeValue system. Code seems a lot cleaner
this way which is a nice advantage. Likely non-functional as this won't
compile just yet and still needs probably another day or two of testing to get
it back to where it was before.
This commit is contained in:
itsmattkc
2019-12-05 03:53:52 +11:00
parent 88c3bd44a5
commit f424d8b44e
14 changed files with 154 additions and 263 deletions
+30 -71
View File
@@ -12,35 +12,6 @@ void AudioRenderWorker::SetParameters(const AudioRenderingParams &audio_params)
audio_params_ = audio_params;
}
QVariant AudioRenderWorker::RenderAsSibling(NodeDependency dep)
{
NodeOutput* output = dep.node();
Node* node = output->parentNode();
QList<NodeInput*> connected_inputs;
QVariant value;
// Set working state
working_++;
// Firstly we check if this node is a "Block", if it is that means it's part of a linked list of mutually exclusive
// nodes based on time and we might need to locate which Block to attach to
if (node->IsBlock()
&& (dep.range().in() < static_cast<Block*>(node)->in()
|| dep.range().out() > static_cast<Block*>(node)->out())) {
// If the range is not wholly contained in this Block, we'll need to do some extra processing
value = RenderBlock(output, dep.range());
} else {
value = ProcessNodeNormally(NodeDependency(output, dep.range()));
}
// We're done!
// End this working state
working_--;
return value;
}
bool AudioRenderWorker::InitInternal()
{
// Nothing to init yet
@@ -52,63 +23,51 @@ void AudioRenderWorker::CloseInternal()
// Nothing to init yet
}
QVariant AudioRenderWorker::RenderBlock(NodeOutput* output, const TimeRange &range)
FramePtr AudioRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRange &range)
{
return decoder->RetrieveAudio(range.in(), range.out() - range.in(), audio_params_);
}
NodeValueTable AudioRenderWorker::RenderBlock(NodeOutput* output, const TimeRange &range)
{
QList<Block*> active_blocks = ValidateBlockRange(static_cast<Block*>(output->parentNode()), range);
// All these blocks will need to output to a buffer so we create one here
QByteArray block_range_buffer(audio_params_.time_to_bytes(range.length()), 0);
NodeValueTable merged_table;
// Loop through active blocks retrieving their audio
while (!active_blocks.isEmpty()) {
int block_for_this_thread = -1;
foreach (Block* b, active_blocks) {
TimeRange range_for_block(qMax(b->in(), range.in()),
qMin(b->out(), range.out()));
for (int i=0;i<active_blocks.size();i++) {
Block* b = active_blocks.at(i);
NodeOutput* connected_output = static_cast<NodeOutput*>(b->GetParameterWithID(output->id()));
NodeValueTable table = RenderAsSibling(NodeDependency(b->block_output(),
range_for_block));
TimeRange range_for_block(qMax(b->in(), range.in()),
qMin(b->out(), range.out()));
QByteArray samples_from_this_block = table.Take(NodeParam::kSamples).toByteArray();
int destination_offset = audio_params_.time_to_bytes(range_for_block.in() - range.in());
int maximum_copy_size = audio_params_.time_to_bytes(range_for_block.length());
int copied_size = 0;
// If the block is locked, we assume another thread has it. Otherwise, we'll work with it
if (connected_output->has_cached_value(range_for_block)) {
// This output already has this value, no need to process it again
QByteArray samples_from_this_block = connected_output->get_cached_value(range_for_block).toByteArray();
if (!samples_from_this_block.isEmpty()) {
copied_size = samples_from_this_block.size();
int destination_offset = audio_params_.time_to_bytes(range_for_block.in() - range.in());
memcpy(block_range_buffer.data()+destination_offset,
samples_from_this_block.data(),
static_cast<size_t>(samples_from_this_block.size()));
active_blocks.removeAt(i);
i--;
} else if (!b->IsProcessingLocked()) {
if (block_for_this_thread == -1) {
block_for_this_thread = i;
} else {
emit RequestSibling(NodeDependency(connected_output,
range_for_block));
}
}
memcpy(block_range_buffer.data()+destination_offset,
samples_from_this_block.data(),
static_cast<size_t>(copied_size));
}
if (block_for_this_thread > -1) {
Block* b = active_blocks.at(block_for_this_thread);
TimeRange range_for_block(qMax(b->in(), range.in()),
qMin(b->out(), range.out()));
RenderAsSibling(NodeDependency(static_cast<NodeOutput*>(b->GetParameterWithID(output->id())),
range_for_block));
} else {
QThread::msleep(500);
if (copied_size < maximum_copy_size) {
memset(block_range_buffer.data()+destination_offset+copied_size,
0,
static_cast<size_t>(maximum_copy_size - copied_size));
}
NodeValueTable::Merge({merged_table, table});
}
return block_range_buffer;
}
merged_table.Push(NodeParam::kSamples, block_range_buffer);
FramePtr AudioRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRange &range)
{
return decoder->RetrieveAudio(range.in(), range.out() - range.in(), audio_params_);
return merged_table;
}