handle rendering from audio engine thread (UI can update)

master
zetaPRIME 2022-03-15 03:56:32 -04:00
parent ff4ffaac61
commit 7858449637
1 changed files with 58 additions and 45 deletions

View File

@ -13,12 +13,16 @@ using namespace Xybrid::Data;
#include <algorithm>
#include <cmath>
#include <iostream>
#include <QDebug>
#include <QThread>
#include <QMutex>
#include <QTimer>
#include <QProcess>
#include <QFileInfo>
#include <QCoreApplication>
#include <QElapsedTimer>
#ifdef Q_OS_MAC
#define FFMPEG "/usr/local/bin/ffmpeg"
@ -219,54 +223,63 @@ void AudioEngine::render(std::shared_ptr<Project> p, QString fileName) {
}
project = p;
queueValid = false;
queue.clear();
portLastNoteId.fill(0);
project->rootGraph->reset();
for (auto& b : buffer) {
b.clear();
b.reserve(static_cast<size_t>(sampleRate/4));
}
seqPos = -1;
curRow = -1;
curTick = -2;
tempo = project->tempo;
tickAcc = 0;
initAudio(); // we actually need the period size. whoops.
QFileInfo fi(fileName);
auto ext = fi.suffix().toLower();
QProcess enc;
QStringList param;
param << "-y" << "-f" << "s16le" << "-ac" << "2" << "-ar" << QString::number(sampleRate) << "-i" << "pipe:";
if (!project->title.isEmpty()) param << "-metadata" << qs("title=%1").arg(project->title);
if (!project->artist.isEmpty()) param << "-metadata" << qs("artist=%1").arg(project->artist);
// flac out is pretty simple, as it turns out
if (ext == "flac") param << "-c:a" << "flac" << "-compression_level" << "8";
// else specify mp3, vbr v0
else param << "-f" << "mp3" << "-codec:a" << "libmp3lame"<< "-q:a" << "0";
param << fileName;
enc.start(FFMPEG, param);
enc.waitForStarted();
std::vector<char> dat;
dat.resize(1024);
mode = Rendering;
while (mode == Rendering) {
enc.write(&dat[0], readData(&dat[0], 1024));
//enc.write(read(1024));
}
enc.closeWriteChannel();
enc.waitForFinished();
QMetaObject::invokeMethod(this, [this, fileName] {
queueValid = false;
queue.clear();
portLastNoteId.fill(0);
project->rootGraph->reset();
for (auto& b : buffer) {
b.clear();
b.reserve(static_cast<size_t>(sampleRate/4));
}
seqPos = -1;
curRow = -1;
curTick = -2;
tempo = project->tempo;
tickAcc = 0;
initAudio(); // we actually need the period size. whoops.
QFileInfo fi(fileName);
auto ext = fi.suffix().toLower();
QProcess enc;
QStringList param;
param << "-y" << "-f" << "s16le" << "-ac" << "2" << "-ar" << QString::number(sampleRate) << "-i" << "pipe:";
if (!project->title.isEmpty()) param << "-metadata" << qs("title=%1").arg(project->title);
if (!project->artist.isEmpty()) param << "-metadata" << qs("artist=%1").arg(project->artist);
// flac out is pretty simple, as it turns out
if (ext == "flac") param << "-c:a" << "flac" << "-compression_level" << "8";
// else specify mp3, vbr v0
else param << "-f" << "mp3" << "-codec:a" << "libmp3lame"<< "-q:a" << "0";
param << fileName;
enc.start(FFMPEG, param);
enc.waitForStarted();
std::vector<char> dat;
dat.resize(1024);
//QElapsedTimer timer;
//timer.start();
//mode = Rendering;
while (mode == Rendering) {
enc.write(&dat[0], readData(&dat[0], 1024));
}
//std::cout << "Render finished in " << static_cast<float>(timer.elapsed())/1000 << " seconds." << std::endl;
enc.closeWriteChannel();
enc.waitForFinished();
stop();
});
while (mode == Rendering) QCoreApplication::processEvents(); // hold modality but allow updates
stop();
//qDebug() << enc.readAllStandardOutput();
//qDebug() << enc.readAllStandardError();