feat: audio stack performance improvements
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user