prep for double-buffer switchover...
parent
be67e02004
commit
8b020975cc
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Xybrid::Audio {
|
||||||
|
typedef float bufferType;
|
||||||
|
}
|
|
@ -406,8 +406,8 @@ qint64 AudioEngine::readData(char *data, qint64 maxlen) {
|
||||||
// convert non-interleaved floating point into interleaved int16
|
// convert non-interleaved floating point into interleaved int16
|
||||||
int16_t* l = reinterpret_cast<int16_t*>(data);
|
int16_t* l = reinterpret_cast<int16_t*>(data);
|
||||||
int16_t* r = reinterpret_cast<int16_t*>(data+smp);
|
int16_t* r = reinterpret_cast<int16_t*>(data+smp);
|
||||||
*l = static_cast<int16_t>(std::clamp(buffer[0][bufPos] * 32768.0f, -32767.0f, 32767.0f));
|
*l = static_cast<int16_t>(std::clamp(buffer[0][bufPos] * 32768.0, -32767.0, 32767.0));
|
||||||
*r = static_cast<int16_t>(std::clamp(buffer[1][bufPos] * 32768.0f, -32767.0f, 32767.0f));
|
*r = static_cast<int16_t>(std::clamp(buffer[1][bufPos] * 32768.0, -32767.0, 32767.0));
|
||||||
|
|
||||||
bufPos++;
|
bufPos++;
|
||||||
data += stride;
|
data += stride;
|
||||||
|
@ -470,7 +470,7 @@ void AudioEngine::nextTick() {
|
||||||
processNodes();
|
processNodes();
|
||||||
if (auto p = std::static_pointer_cast<AudioPort>(project->rootGraph->port(Port::Output, Port::Audio, 0)); p) {
|
if (auto p = std::static_pointer_cast<AudioPort>(project->rootGraph->port(Port::Output, Port::Audio, 0)); p) {
|
||||||
p->pull();
|
p->pull();
|
||||||
size_t bufs = ts * sizeof(float);
|
size_t bufs = ts * sizeof(bufferType);
|
||||||
memcpy(buffer[0].data(), p->bufL, bufs);
|
memcpy(buffer[0].data(), p->bufL, bufs);
|
||||||
memcpy(buffer[1].data(), p->bufR, bufs);
|
memcpy(buffer[1].data(), p->bufR, bufs);
|
||||||
}
|
}
|
||||||
|
@ -654,7 +654,7 @@ void AudioEngine::nextTick() {
|
||||||
processNodes();
|
processNodes();
|
||||||
if (auto p = std::static_pointer_cast<AudioPort>(project->rootGraph->port(Port::Output, Port::Audio, 0)); p) {
|
if (auto p = std::static_pointer_cast<AudioPort>(project->rootGraph->port(Port::Output, Port::Audio, 0)); p) {
|
||||||
p->pull();
|
p->pull();
|
||||||
size_t bufs = ts * sizeof(float);
|
size_t bufs = ts * sizeof(bufferType);
|
||||||
memcpy(buffer[0].data(), p->bufL, bufs);
|
memcpy(buffer[0].data(), p->bufL, bufs);
|
||||||
memcpy(buffer[1].data(), p->bufR, bufs);
|
memcpy(buffer[1].data(), p->bufR, bufs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
|
|
||||||
|
#include "audio/audio.h"
|
||||||
|
|
||||||
class QThread;
|
class QThread;
|
||||||
namespace Xybrid::Data {
|
namespace Xybrid::Data {
|
||||||
class Project;
|
class Project;
|
||||||
|
@ -57,11 +59,12 @@ namespace Xybrid::Audio {
|
||||||
int sampleRate = 48000;
|
int sampleRate = 48000;
|
||||||
int bufferMs = 64;
|
int bufferMs = 64;
|
||||||
|
|
||||||
std::vector<float> buffer[2];
|
std::vector<bufferType> buffer[2];
|
||||||
size_t bufPos = 0;
|
size_t bufPos = 0;
|
||||||
//std::vector<char> outBuf;
|
//std::vector<char> outBuf;
|
||||||
|
|
||||||
static const constexpr size_t tickBufSize = (1024*1024*5); // 5mb should be enough
|
// 32MiB really isn't much to take up for being a far higher ceiling than we should ever need
|
||||||
|
static const constexpr size_t tickBufSize = (1024*1024*32);
|
||||||
std::unique_ptr<size_t[]> tickBuf;
|
std::unique_ptr<size_t[]> tickBuf;
|
||||||
std::atomic<size_t*> tickBufPtr;
|
std::atomic<size_t*> tickBufPtr;
|
||||||
size_t* tickBufEnd;
|
size_t* tickBufEnd;
|
||||||
|
|
|
@ -14,7 +14,7 @@ void AudioPort::pull() {
|
||||||
|
|
||||||
size_t ts = audioEngine->curTickSize();
|
size_t ts = audioEngine->curTickSize();
|
||||||
size = ts;
|
size = ts;
|
||||||
size_t s = sizeof(float) * ts;
|
size_t s = sizeof(bufferType) * ts;
|
||||||
|
|
||||||
if (type == Input) {
|
if (type == Input) {
|
||||||
if (connections.size() == 1) {
|
if (connections.size() == 1) {
|
||||||
|
@ -26,7 +26,7 @@ void AudioPort::pull() {
|
||||||
goto done;//return;
|
goto done;//return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bufL = static_cast<float*>(audioEngine->tickAlloc(s*2));
|
bufL = static_cast<bufferType*>(audioEngine->tickAlloc(s*2));
|
||||||
bufR = &bufL[ts]; // for some reason just adding the size wonks out
|
bufR = &bufL[ts]; // for some reason just adding the size wonks out
|
||||||
memset(bufL, 0, s*2); // clear buffers
|
memset(bufL, 0, s*2); // clear buffers
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ void AudioPort::pull() {
|
||||||
bufL = pt->bufL;
|
bufL = pt->bufL;
|
||||||
bufR = pt->bufR;
|
bufR = pt->bufR;
|
||||||
} else { // output without valid passthrough, just clear and prepare a blank buffer
|
} else { // output without valid passthrough, just clear and prepare a blank buffer
|
||||||
bufL = static_cast<float*>(audioEngine->tickAlloc(s*2));
|
bufL = static_cast<bufferType*>(audioEngine->tickAlloc(s*2));
|
||||||
bufR = &bufL[ts];
|
bufR = &bufL[ts];
|
||||||
memset(bufL, 0, s*2); // clear buffers
|
memset(bufL, 0, s*2); // clear buffers
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "data/node.h"
|
#include "data/node.h"
|
||||||
#include "data/audioframe.h"
|
#include "data/audioframe.h"
|
||||||
|
#include "audio/audio.h"
|
||||||
|
|
||||||
namespace Xybrid::Data {
|
namespace Xybrid::Data {
|
||||||
class AudioPort : public Port {
|
class AudioPort : public Port {
|
||||||
|
@ -13,21 +14,21 @@ namespace Xybrid::Data {
|
||||||
FrameRef(AudioPort* port, size_t at) : port(port), at(at) { }
|
FrameRef(AudioPort* port, size_t at) : port(port), at(at) { }
|
||||||
public:
|
public:
|
||||||
FrameRef& operator=(AudioFrame f) {
|
FrameRef& operator=(AudioFrame f) {
|
||||||
port->bufL[at] = static_cast<float>(f.l);
|
port->bufL[at] = static_cast<Audio::bufferType>(f.l);
|
||||||
port->bufR[at] = static_cast<float>(f.r);
|
port->bufR[at] = static_cast<Audio::bufferType>(f.r);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
FrameRef& operator+=(AudioFrame f) {
|
FrameRef& operator+=(AudioFrame f) {
|
||||||
port->bufL[at] += static_cast<float>(f.l);
|
port->bufL[at] += static_cast<Audio::bufferType>(f.l);
|
||||||
port->bufR[at] += static_cast<float>(f.r);
|
port->bufR[at] += static_cast<Audio::bufferType>(f.r);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
operator AudioFrame() const { return { port->bufL[at], port->bufR[at] }; }
|
operator AudioFrame() const { return { port->bufL[at], port->bufR[at] }; }
|
||||||
AudioFrame operator*(AudioFrame o) const { return static_cast<AudioFrame>(*this) * o; }
|
AudioFrame operator*(AudioFrame o) const { return static_cast<AudioFrame>(*this) * o; }
|
||||||
};
|
};
|
||||||
|
|
||||||
float* bufL;
|
Audio::bufferType* bufL;
|
||||||
float* bufR;
|
Audio::bufferType* bufR;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
AudioPort() = default;
|
AudioPort() = default;
|
||||||
|
|
Loading…
Reference in New Issue