Files
oak-editor/app/render/backend/audio/audiobackend.cpp
T

117 lines
3.1 KiB
C++

/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
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 3 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. If not, see <http://www.gnu.org/licenses/>.
***/
#include "audiobackend.h"
#include "audioworker.h"
OLIVE_NAMESPACE_ENTER
AudioBackend::AudioBackend(QObject *parent) :
AudioRenderBackend(parent)
{
}
AudioBackend::~AudioBackend()
{
Close();
}
bool AudioBackend::InitInternal()
{
// Initiate one thread per CPU core
for (int i=0;i<threads().size();i++) {
// Create one processor object for each thread
AudioWorker* processor = new AudioWorker(&node_copy_map_);
processor->SetParameters(params());
processors_.append(processor);
}
return true;
}
void AudioBackend::CloseInternal()
{
}
void AudioBackend::ConnectWorkerToThis(RenderWorker *worker)
{
AudioRenderBackend::ConnectWorkerToThis(worker);
connect(worker, &RenderWorker::CompletedCache, this, &AudioBackend::ThreadCompletedCache);
}
void AudioBackend::ThreadCompletedCache(NodeDependency dep, NodeValueTable data, qint64 job_time)
{
SetWorkerBusyState(static_cast<RenderWorker*>(sender()), false);
if (job_time == render_job_info_.value(dep.range())) {
render_job_info_.remove(dep.range());
SampleBufferPtr cached_sample_ptr = data.Get(NodeParam::kSamples).value<SampleBufferPtr>();
if (cached_sample_ptr) {
QByteArray cached_samples = cached_sample_ptr->toPackedData();
int offset = params().time_to_bytes(dep.in());
int length = params().time_to_bytes(dep.range().length());
int out_point = qMin(offset + length, params().time_to_bytes(GetSequenceLength()));
if (offset < out_point) {
if (offset + length > out_point) {
length = out_point - offset;
}
QFile f(CachePathName());
if (f.open(QFile::ReadWrite)) {
if (f.size() < out_point && !f.resize(out_point)) {
qCritical() << "Failed to resize file" << CachePathName();
}
if (!f.seek(offset)) {
qCritical() << "Failed to seek file" << CachePathName();
}
// Replace data with this data
int copy_length = qMin(length, cached_samples.size());
f.write(cached_samples.data(), copy_length);
if (copy_length < length) {
// Fill in remainder with silence
QByteArray empty_space(length - copy_length, 0);
f.write(empty_space);
}
f.close();
} else {
qWarning() << "Failed to write to cached PCM file";
}
}
}
}
CacheNext();
}
OLIVE_NAMESPACE_EXIT