audio: switch waveout backend to pull rendering

This commit is contained in:
2026-04-14 19:04:18 +08:00
parent e77dbe40b1
commit 882df1ae5a
10 changed files with 378 additions and 94 deletions

View File

@@ -78,6 +78,60 @@ public:
uint32 lastSampleRate = 0;
};
class PullCaptureBackend final : public IAudioBackend {
public:
explicit PullCaptureBackend(const AudioConfig& inConfig) : config(inConfig) {}
bool Initialize(const AudioConfig& inConfig) override {
config = inConfig;
return true;
}
void Shutdown() override {}
std::string GetDeviceName() const override { return "PullCaptureBackend"; }
void GetAvailableDevices(std::vector<std::string>& devices) override {
devices = {"PullCaptureBackend"};
}
bool SetDevice(const std::string& deviceName) override { return deviceName == "PullCaptureBackend"; }
void Start() override { running = true; }
void Stop() override { running = false; }
void Suspend() override {}
void Resume() override {}
void ProcessAudio(float* buffer, uint32 frameCount, uint32 channels, uint32 sampleRate) override {
(void)buffer;
(void)frameCount;
(void)channels;
(void)sampleRate;
submissionCount++;
}
bool UsesPullModel() const override { return true; }
void SetRenderCallback(RenderCallback callback) override { renderCallback = callback; }
bool IsRunning() const override { return running; }
AudioConfig GetConfig() const override { return config; }
bool RenderOnce() {
if (!renderCallback) {
return false;
}
const size_t sampleCount = static_cast<size_t>(config.bufferSize) * config.channels;
captured.assign(sampleCount, 0.0f);
renderCallback(captured.data(), config.bufferSize, config.channels, config.sampleRate);
return true;
}
AudioConfig config{};
std::vector<float> captured;
RenderCallback renderCallback;
bool running = true;
uint32 submissionCount = 0;
};
TEST(AudioSystem, MasterMixerProcessesDirectSources) {
AudioSystem& system = AudioSystem::Get();
system.Shutdown();
@@ -318,6 +372,40 @@ TEST(AudioSystem, RenderAudioProducesMixedBlockWithoutBackendSubmission) {
system.Shutdown();
}
TEST(AudioSystem, PullBackendRendersViaCallbackWithoutPushSubmission) {
AudioSystem& system = AudioSystem::Get();
system.Shutdown();
AudioConfig config;
config.sampleRate = 4;
config.channels = 1;
config.bufferSize = 1;
auto backend = std::make_unique<PullCaptureBackend>(config);
PullCaptureBackend* backendPtr = backend.get();
system.SetBackend(std::move(backend));
system.SetMasterVolume(0.5f);
system.SetMuted(false);
system.GetMasterMixer().ClearEffects();
AudioClip clip = CreateMono16Clip({16384}, 4);
AudioSourceComponent source;
source.SetSpatialize(false);
source.SetClip(&clip);
source.Play();
system.Update(0.0f);
EXPECT_EQ(backendPtr->submissionCount, 0u);
ASSERT_TRUE(backendPtr->RenderOnce());
ASSERT_EQ(backendPtr->captured.size(), 1u);
EXPECT_NEAR(backendPtr->captured[0], 0.25f, 1e-5f);
source.Stop();
system.SetMasterVolume(1.0f);
system.Shutdown();
}
TEST(AudioSystem, AudioListenerComponentSerializeRoundTripPreservesSettings) {
AudioSystem& system = AudioSystem::Get();
system.Shutdown();