nonfunctional flailing

master
zetaPRIME 2022-03-19 16:25:31 -04:00
parent e78cebfd77
commit 6fcc6db4e6
3 changed files with 53 additions and 5 deletions

5
notes
View File

@ -40,7 +40,10 @@ TODO {
}
}
- ping-pong for delay
filter cutoff preset for knobgadget
force at least 1hz in svfilter for normalization
x retool audio engine for active push
revert-to-saved menu action

View File

@ -107,10 +107,12 @@ void AudioEngine::initAudio(bool startNow) {
output.reset(new QAudioOutput(deviceInfo, format));
output->setCategory("Xybrid");
output->setObjectName("Xybrid"); // if Qt ever implements naming the stream this way, WE'LL BE READY
output->setBufferSize(static_cast<int>(sampleRate*4*( 64.0 )/1000.0)); // 64ms seems to be a sweet spot now
//output->setBufferSize(static_cast<int>(sampleRate*4*( 64.0 )/1000.0)); // 64ms seems to be a sweet spot now
connect(output.get(), &QAudioOutput::notify, this, &AudioEngine::processActive);
}
if (startNow) output->start();
if (startNow) startOutput();
}
void AudioEngine::deinitAudio() {
@ -124,6 +126,23 @@ void AudioEngine::deinitAudio() {
}
}
void AudioEngine::startOutput() {
if (!output) return;
if (activeBuffering) {
outBuf.resize(static_cast<size_t>(4*5*sampleRate/1000));
output->setBufferSize(sampleRate*4*(bufferMs+250)/1000); // allocate extra buffer for safety
output->setNotifyInterval(std::max(1, bufferMs/2));
outStream = output->start();
bufferFill = output->notifyInterval();
assert(bufferFill > 0);
} else {
outBuf.resize(0);
output->setNotifyInterval(0); // don't need this here
output->setBufferSize(sampleRate*4*bufferMs/1000); // set canonical buffer size
output->start(this); // set output to take the active role
}
}
void AudioEngine::play(std::shared_ptr<Project> p, int fromPos) {
QMetaObject::invokeMethod(this, [this, p, fromPos] {
if (!p) return; // nope
@ -147,7 +166,7 @@ void AudioEngine::play(std::shared_ptr<Project> p, int fromPos) {
tempo = project->tempo;
tickAcc = 0;
output->start(this);
startOutput();
mode = Playing;
emit this->playbackModeChanged();
@ -193,7 +212,7 @@ uint16_t AudioEngine::preview(std::shared_ptr<Project> p, int16_t port, int16_t
}
tempo = project->tempo;
output->start(this);
startOutput();
mode = Previewing;
emit this->playbackModeChanged();
}
@ -351,6 +370,23 @@ void AudioEngine::buildQueue() {
queueValid = true;
}
void AudioEngine::processActive() {
if (!output || !activeBuffering) return;
bufferFill -= output->notifyInterval();
qint64 needed = (bufferMs - bufferFill) * sampleRate/1000 * 4;
while (needed > 0) {
auto r = readData(&outBuf[0], std::min(needed, static_cast<qint64>(outBuf.size())));
outStream->write(&outBuf[0], r);
needed -= r;
//enc.write(&dat[0], readData(&dat[0], 1024));
}
bufferFill = bufferMs;
//
}
qint64 AudioEngine::readData(char *data, qint64 maxlen) {
const constexpr qint64 smp = 2;
const constexpr qint64 stride = smp*2;

View File

@ -53,6 +53,7 @@ namespace Xybrid::Audio {
private:
QThread* thread;
std::unique_ptr<QAudioOutput> output;
QIODevice* outStream;
int sampleRate = 48000;
std::vector<float> buffer[2];
@ -63,6 +64,11 @@ namespace Xybrid::Audio {
std::atomic<size_t*> tickBufPtr;
size_t* tickBufEnd;
static const constexpr bool activeBuffering = false;//true;
int bufferMs = 64;
int bufferFill = 0;
std::vector<char> outBuf;
PlaybackMode mode = Stopped;
size_t tickId = 0;
std::shared_ptr<Data::Project> project;
@ -95,9 +101,11 @@ namespace Xybrid::Audio {
void postInit();
void initAudio(bool startNow = false);
void deinitAudio();
void startOutput();
Data::Pattern* findPattern(int = 0);
void nextTick();
void processNodes();
public:
static void init();
inline constexpr PlaybackMode playbackMode() const { return mode; }
@ -125,6 +133,7 @@ namespace Xybrid::Audio {
void playbackModeChanged();
public slots:
void processActive();
};
class AudioWorker : public QObject, private AudioWorkerCore {