nonfunctional flailing
parent
e78cebfd77
commit
6fcc6db4e6
5
notes
5
notes
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue