Moved common CPU easing calculations from DirectSoundOut and WasapiOut and

into Player. This also fixes Visualizer sluggishness.
This commit is contained in:
casey langen 2016-12-29 16:05:42 -08:00
parent 887fd77516
commit 1c68635e4d
5 changed files with 14 additions and 16 deletions

View File

@ -120,7 +120,6 @@ DirectSoundOut::DirectSoundOut()
, latency(0)
, rate(0)
, channels(0)
, minWaitTimeMs(0)
, firstBufferWritten(false)
, volume(1.0f) {
ZeroMemory(&waveFormat, sizeof(WAVEFORMATEXTENSIBLE));
@ -215,8 +214,7 @@ int DirectSoundOut::Play(IBuffer *buffer, IBufferProvider *provider) {
if (bufferBytes > availableBytes && this->state == StatePlaying) {
int samples = (bufferBytes - availableBytes) / sizeof(float) / channels;
int sleepMs = ((long long)(samples * 1000) / rate) + 1;
return std::max(minWaitTimeMs, sleepMs); /* we'll be called back in sleepMs seconds. */
return ((long long)(samples * 1000) / rate) + 1;
}
assert(availableBytes >= bufferBytes);
@ -486,7 +484,6 @@ bool DirectSoundOut::Configure(IBuffer *buffer) {
int samples = this->bufferSize / sizeof(float) / channels;
this->latency = (float)samples / (float)rate;
minWaitTimeMs = (int) (this->latency * 1000.0) * 0.25;
this->state = StatePlaying;
this->SetVolume(this->volume);

View File

@ -91,7 +91,6 @@ class DirectSoundOut : public IOutput {
int channels;
double volume;
double latency;
int minWaitTimeMs;
bool firstBufferWritten;
std::recursive_mutex stateMutex;
};

View File

@ -62,8 +62,7 @@ WasapiOut::WasapiOut()
, outputBufferFrames(0)
, state(StateStopped)
, latency(0)
, volume(1.0f)
, minWaitTimeMs(0) {
, volume(1.0f) {
ZeroMemory(&waveFormat, sizeof(WAVEFORMATEXTENSIBLE));
}
@ -172,12 +171,7 @@ int WasapiOut::Play(IBuffer *buffer, IBufferProvider *provider) {
if (availableFrames < framesToWrite) {
UINT32 delta = framesToWrite - availableFrames;
int sleepTimeMs = (delta * 1000) / buffer->SampleRate();
/* sleep at least minWaitTimeMs millis! our buffer is full,
so we can afford to wait for ~10% of it to deplete to
ease the CPU load a bit. */
return std::max(minWaitTimeMs, sleepTimeMs);
return (delta * 1000) / buffer->SampleRate();
}
if (availableFrames >= framesToWrite) {
@ -325,7 +319,6 @@ bool WasapiOut::Configure(IBuffer *buffer) {
}
this->latency = (float) outputBufferFrames / (float) buffer->SampleRate();
this->minWaitTimeMs = (int)((this->latency * 1000.0) * 0.25);
if ((result = this->audioClient->GetService(__uuidof(IAudioRenderClient), (void**) &this->renderClient)) != S_OK) {
std::cerr << "WasapiOut: IAudioClient::GetService failed, error code = " << result << "\n";

View File

@ -91,6 +91,5 @@ class WasapiOut : public IOutput {
double volume;
double latency;
int rate;
int minWaitTimeMs;
std::recursive_mutex stateMutex;
};

View File

@ -340,7 +340,17 @@ void musik::core::audio::playerThreadLoop(Player* player) {
more than a second, try to push the buffer into the output again. this
may happen if the sound driver has some sort of transient problem and
is temporarily unable to process the bufer (ALSA, i'm looking at you) */
int sleepMs = (playResult >= 0) ? playResult : 1000;
int sleepMs = playResult;
/* if we were asked to sleep, that means the output's buffer is full, so
we'll ease load on the CPU a bit by introducing an artifical delay --
about 25% of the buffer size. however, we won't do this if visualizer is
open becuase it makes things a bit jerky. */
auto visualizer = vis::SelectedVisualizer();
if (playResult >= 0 && (!visualizer || !visualizer->Visible())) {
sleepMs = std::max((int)(player->output->Latency() * 250), sleepMs);
}
std::unique_lock<std::mutex> lock(player->queueMutex);
player->writeToOutputCondition.wait_for(lock, std::chrono::milliseconds(sleepMs));
}