feat: audio stack performance improvements

This commit is contained in:
2026-05-19 18:13:37 +02:00
parent 01ed473471
commit 79284083ca
4 changed files with 86 additions and 15 deletions
+33 -11
View File
@@ -164,9 +164,16 @@ namespace Drivers::Audio::Mixer {
static void Pump() {
if (!g_hdaOpened) return;
// Ask IntelHda how much room there is. The driver clamps writes to free
// space, so we feed it a generous buffer and let it consume what it can.
uint32_t frames = MAX_PUMP_FRAMES;
// Produce only as many frames as the HDA DMA ring has room for right
// now. Producing more would mean the surplus is silently dropped by
// IntelHda::Write while the per-stream resamplers had already
// advanced — that's what scrambles speech into a sequence of
// unrelated chunks. Clamp to MAX_PUMP_FRAMES so the scratch buffers
// are bounded.
uint32_t freeBytes = IntelHda::GetWriteSpace(g_hdaHandle);
uint32_t frames = freeBytes / 4;
if (frames == 0) return;
if (frames > MAX_PUMP_FRAMES) frames = MAX_PUMP_FRAMES;
// Always write to HDA, even when no streams are active, so the
// hardware ring stays filled with silence instead of looping the
@@ -448,15 +455,26 @@ namespace Drivers::Audio::Mixer {
void SetMasterVolume(int percent) {
if (percent < 0) percent = 0;
if (percent > 100) percent = 100;
// Take the mixer lock just long enough to update software state and
// capture a snapshot for the HW write. The IntelHda codec command
// path busy-waits on the RIRB for a few hundred microseconds, so
// doing it inside the lock would freeze interrupts (BCIS, scheduler,
// input) for the whole duration of every drag tick — visible as
// slider lag.
g_lock.Acquire();
bool changed = (g_masterVolume != percent);
g_masterVolume = percent;
if (g_hdaOpened) {
IntelHda::Control(g_hdaHandle, IntelHda::AUDIO_CTL_SET_VOLUME,
g_masterMute ? 0 : g_masterVolume);
}
int curVol = g_masterVolume;
bool curMute = g_masterMute;
bool hdaOpen = g_hdaOpened;
if (changed) BumpSerialLocked();
g_lock.Release();
if (changed && hdaOpen) {
IntelHda::Control(g_hdaHandle, IntelHda::AUDIO_CTL_SET_VOLUME,
curMute ? 0 : curVol);
}
if (changed) Sched::WakeObjectWaiters((void*)&g_serial);
}
@@ -468,12 +486,16 @@ namespace Drivers::Audio::Mixer {
g_lock.Acquire();
bool changed = (g_masterMute != muted);
g_masterMute = muted;
if (g_hdaOpened) {
IntelHda::Control(g_hdaHandle, IntelHda::AUDIO_CTL_SET_VOLUME,
g_masterMute ? 0 : g_masterVolume);
}
int curVol = g_masterVolume;
bool curMute = g_masterMute;
bool hdaOpen = g_hdaOpened;
if (changed) BumpSerialLocked();
g_lock.Release();
if (changed && hdaOpen) {
IntelHda::Control(g_hdaHandle, IntelHda::AUDIO_CTL_SET_VOLUME,
curMute ? 0 : curVol);
}
if (changed) Sched::WakeObjectWaiters((void*)&g_serial);
}