Skip to content

Commit

Permalink
A few small performance tweaks
Browse files Browse the repository at this point in the history
Turns out the active voice calculation was kidna expensive
as were VUs on busses we weren't using, so do a couple of
little optimizations for each of those.

The bug ones (don't evaluate busses with no activity at all)
still isn't done.

Addresses #1068
  • Loading branch information
baconpaul committed Aug 5, 2024
1 parent 9c23c1d commit 9d0ef31
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 7 deletions.
10 changes: 9 additions & 1 deletion src/engine/bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,15 @@ void Bus::process()
for (int c = 0; c < 2; ++c)
{
vuLevel[c] = std::min(2.f, a * vuLevel[c]);
vuLevel[c] = std::max((float)vuLevel[c], mech::blockAbsMax<BLOCK_SIZE>(output[c]));
/* we use this as a proxy for a silent block without having to scan the entire
* block. If the block isn't silent, we will get the next vlock if we just get
* unlucky with sample 0 except in a super pathological case of an exactly
* 16 sample sin wave or something.
*/
if (std::fabs(output[c][0]) > 1e-15)
{
vuLevel[c] = std::max((float)vuLevel[c], mech::blockAbsMax<BLOCK_SIZE>(output[c]));
}
}
}

Expand Down
13 changes: 9 additions & 4 deletions src/engine/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ voice::Voice *Engine::initiateVoice(const pathToZone_t &path)
voices[idx]->noteId = path.noteid;
voices[idx]->setSampleRate(sampleRate, sampleRateInv);
voices[idx]->endpoints = std::move(mp);
activeVoices++;
return voices[idx];
}
}
Expand Down Expand Up @@ -248,7 +249,7 @@ bool Engine::processAudio()
#endif
messageController->engineProcessRuns++;
messageController->isAudioRunning = true;
auto av = activeVoiceCount();
auto av = (uint32_t)activeVoices;

bool tryToDrain{true};
while (tryToDrain && !messageController->serializationToAudioQueue.empty())
Expand Down Expand Up @@ -316,7 +317,11 @@ bool Engine::processAudio()
bl[idx++][c] = a.vuLevel[c];
}

auto pav = activeVoiceCount();
auto pav = (uint32_t)activeVoices;
#if BUILD_IS_DEBUG
if (pav != av)
assertActiveVoiceCount();
#endif

bool doUpdate = messageController->isClientConnected &&
(
Expand Down Expand Up @@ -372,15 +377,15 @@ bool Engine::processAudio()
return true;
}

uint32_t Engine::activeVoiceCount()
void Engine::assertActiveVoiceCount()
{
uint32_t res{0};
for (const auto v : voices)
{
if (v)
res += (v->isVoiceAssigned && v->isVoicePlaying);
}
return res;
assert(res == activeVoices);
}

const std::optional<dsp::processor::ProcessorStorage>
Expand Down
3 changes: 2 additions & 1 deletion src/engine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ struct Engine : MoveableOnly<Engine>, SampleRateSupport
void stopAllSounds();

// TODO: All this gets ripped out when voice management is fixed
uint32_t activeVoiceCount();
void assertActiveVoiceCount();
std::atomic<uint32_t> activeVoices{0};

const std::unique_ptr<messaging::MessageController> &getMessageController() const
{
Expand Down
1 change: 1 addition & 0 deletions src/voice/voice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void Voice::cleanupVoice()
zone = nullptr;
isVoiceAssigned = false;
engine->voiceManagerResponder.doVoiceEndCallback(this);
engine->activeVoices--;

// We cleanup processors here since they may have, say,
// memory pool resources checked out that others could
Expand Down
1 change: 1 addition & 0 deletions src/voice/voice.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ struct alignas(16) Voice : MoveableOnly<Voice>,

isVoicePlaying = true;
isVoiceAssigned = true;

voiceStarted();
}
void release() { isGated = false; }
Expand Down

0 comments on commit 9d0ef31

Please sign in to comment.