| @@ -221,6 +221,7 @@ struct AudioInterface : Module, audio::Port { | |||
| // audio::Port | |||
| void processInput(const float* input, int inputStride, int frames) override { | |||
| // DEBUG("%p: new device block ____________________________", this); | |||
| // Claim primary module if there is none | |||
| if (!APP->engine->getPrimaryModule()) { | |||
| setPrimary(); | |||
| @@ -235,18 +236,18 @@ struct AudioInterface : Module, audio::Port { | |||
| float engineSampleRate = APP->engine->getSampleRate(); | |||
| float sampleRateRatio = engineSampleRate / deviceSampleRate; | |||
| DEBUG("%p: %d block, engineOutputBuffer %d", this, frames, (int) engineOutputBuffer.size()); | |||
| // DEBUG("%p: %d block, engineOutputBuffer still has %d", this, frames, (int) engineOutputBuffer.size()); | |||
| // Consider engine buffers "too full" if they contain a bit more than the audio device's number of frames, converted to engine sample rate. | |||
| int maxEngineFrames = (int) std::ceil(frames * sampleRateRatio * 2.0) - 1; | |||
| // If the engine output buffer is too full, flush it to keep latency low. No need to flush if primary because it's always flushed below. | |||
| // If the engine output buffer is too full, clear it to keep latency low. No need to clear if primary because it's always cleared below. | |||
| if (!isPrimaryCached && (int) engineOutputBuffer.size() > maxEngineFrames) { | |||
| engineOutputBuffer.clear(); | |||
| DEBUG("%p: flushing engine output", this); | |||
| // DEBUG("%p: clearing engine output", this); | |||
| } | |||
| if (deviceNumInputs > 0) { | |||
| // Always flush engine output if primary | |||
| // Always clear engine output if primary | |||
| if (isPrimaryCached) { | |||
| engineOutputBuffer.clear(); | |||
| } | |||
| @@ -278,13 +279,13 @@ struct AudioInterface : Module, audio::Port { | |||
| void processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames) override { | |||
| // Step engine | |||
| if (isPrimary() && requestedEngineFrames > 0) { | |||
| DEBUG("%p: %d block, stepping %d", this, frames, requestedEngineFrames); | |||
| // DEBUG("%p: %d block, stepping %d", this, frames, requestedEngineFrames); | |||
| APP->engine->stepBlock(requestedEngineFrames); | |||
| } | |||
| } | |||
| void processOutput(float* output, int outputStride, int frames) override { | |||
| bool isPrimaryCached = isPrimary(); | |||
| // bool isPrimaryCached = isPrimary(); | |||
| float engineSampleRate = APP->engine->getSampleRate(); | |||
| float sampleRateRatio = engineSampleRate / deviceSampleRate; | |||
| @@ -314,13 +315,13 @@ struct AudioInterface : Module, audio::Port { | |||
| } | |||
| } | |||
| DEBUG("%p: %d block, inputFrames %d", this, frames, (int) engineInputBuffer.size()); | |||
| // DEBUG("%p: %d block, engineInputBuffer left %d", this, frames, (int) engineInputBuffer.size()); | |||
| // If the engine input buffer is too full, flush it to keep latency low. | |||
| // If the engine input buffer is too full, clear it to keep latency low. | |||
| int maxEngineFrames = (int) std::ceil(frames * sampleRateRatio * 2.0) - 1; | |||
| if ((int) engineInputBuffer.size() > maxEngineFrames) { | |||
| engineInputBuffer.clear(); | |||
| DEBUG("%p: flushing engine input", this); | |||
| // DEBUG("%p: clearing engine input", this); | |||
| } | |||
| // DEBUG("%p %s:\tframes %d requestedEngineFrames %d\toutputBuffer %d engineInputBuffer %d\t", this, isPrimaryCached ? "primary" : "secondary", frames, requestedEngineFrames, engineOutputBuffer.size(), engineInputBuffer.size()); | |||