Repository navigation
tests: wait for the host stream, not the clock, in the audio card tests - #740
Open
jamesbraid wants to merge 2 commits into
Open
jamesbraid wants to merge 2 commits into
jamesbraid wants to merge 2 commits into
Conversation
both_outputs_play_at_their_own_rates_into_one_stream fed both outputs by wall time for 0.7 s, slept 0.2 s and closed the file. The `[audio] file` takes frames on a thread of its own by the host's clock, and a loaded host can hold that thread up for longer than the test lasts. The file is then closed with nothing in it: Test (windows-latest) failed with "sound in the file", the WAV holding no loud stretch at all, while the check that neither output had run dry passed, as it must for a stream whose renderer had not yet played anything. The file is now closed only once both outputs have played everything out, giving up after 30 s. That wait is the fix. The prebuffer goes to 300 ms so the ring ceiling, three prebuffers, holds all 0.7 s while the writer is held up; the default 100 ms ceiling would skip most of it. A ring that runs dry because the writer was held up is the host's real-time behaviour, so the check that neither output ran dry goes. In its place each output must have taken every frame given, with none dropped or skipped, and each side must hold that much sound at its own pitch, counted without the silence a held-up writer leaves. A gap inside the sound is therefore not caught by the file check, only lost frames. A new test holds the file's thread for 1.5 s before it starts its clock. With the old fixed 200 ms wait it failed 5 of 5 runs with no sound in the file.
Two more host-output tests failed on a loaded host. The MACE tone-through-an-underrun test failed 1 of 10 runs pinned to two CPUs beside four busy loops, on its check that the host stream ran dry while the output was stopped. The RAD1 real-clock test failed once in a full run under load and then passed 2 of 3 runs on its own, on its check that the card moved at least half the frames the wall time allowed. The underrun tests of MACE, RAD1 and the ICE1724 slept 0.3 s while the output was stopped, read the underrun count, and slept 0.3 s more before closing the file. The `[audio] file` plays on a thread of its own by the host's clock, and a loaded host can hold that thread up past both sleeps: the count has not risen, or the end of the sound is still queued when the file closes. Each now waits after the pause, and at the end, until the stream has run dry since a count taken just before the stop, giving up after 10 s (60 s for RAD1, its tests' usual limit). MACE and RAD1 also take a 300 ms prebuffer, so the ring's ceiling of three prebuffers holds what the card plays while the writer is held up instead of skipping it, which would cut the sound around the pause short. With that prebuffer the stream still holds 300 ms when the output stops, so a 0.3 s sleep only lets it play out; the pause the capture must show is the 300 ms the restart spends refilling the prebuffer after the drain. Their sleep goes, and the drain is what makes the pause: without it the restart lands on frames still queued and the capture has no silence. The ICE1724 keeps the default 20 ms prebuffer and its 0.3 s sleep, which is its pause. RAD1's timer thread moves the frames, and a busy host can give it no time for most of the test. Its real-clock test now waits until 0.6 s of frames have moved before the mute and 0.3 s more after it, then until the stream has played the tone and 0.1 s past it, and checks that no more frames moved than the host's clock allowed. The lower bound on the clock goes: a held-up timer only makes frames late, and the card's rate is checked against a test clock elsewhere. Its bound on what the file holds now allows 0.5% more, which the file's clock follower gives when it plays slow; 4 of 100 runs on an otherwise idle host heard 50 to 120 frames more than the card played, past the 48 allowed. That the follower is the cause is inferred, not measured. A writer held for 0.8 s from 0.55 s or 0.65 s into the run, injected in a local copy of the file backend, failed the three underrun tests in 18 of 18 runs before this change and in 0 of 18 after. Leaving out the drain after the pause fails MACE and RAD1 3 of 3 runs with no pause heard. A timer held for 1 s failed the RAD1 real-clock test's clock check 3 of 3 runs. It still fails after this change, on the check that the file holds the tone: past two laps of the ring the card credits the frames it missed without playing them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dominik's
both_outputs_play_at_their_own_rates_into_one_streamfailed on Test (windows-latest) with "sound in the file": the[audio] filewriter plays on its own thread by the host's clock, and a loaded runner held it past the test's fixed 0.2 s wait, so the file closed empty. It is racy on main too: holding the file thread for 1.5 s makes main's fixture fail 5 of 5 with the same panic.These two test-only commits make the host-output tests wait for the stream rather than the clock:
Verification: an injected 0.8 s writer hold failed the three underrun tests 18 of 18 times before and 0 of 18 after. Ten loops under four busy loops on two CPUs pass for the MACE, HAL2, RAD1, ICE1724 and host_audio tests.
Known and unchanged: with a timer held for 1 s, RAD1's real-clock test still fails, because past two laps of the ring the card credits frames it missed without playing them.