Repository navigation
UAC host: play and record at once, one stream per direction - #86
Merged
Merged
Conversation
The host kept one UAC stream, so a board could play to a device or record from it, never both. It now keeps one per direction: an output and an input open side by side, on the same device (a headset, a DAC looped into its own input) or on two. Each has its own transfers, ring and counters, and a transfer carries its stream in its context. queued, space, capacity, stats and close take the stream's endpoint; without one they keep their old meaning, and uac_audio falls back to that on firmware from before. UacHostInput gains available(). Closing a stream now sets the device's interface back to alt 0. Releasing the interface never did: IDF sends no SET_INTERFACE, so a closed stream left the device streaming.
…back and capture run together
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.
A board hosting a USB sound card can now play to it and record from it at the same time. Open
uac_audio.output(dev)anduac_audio.input(dev)side by side, on one device (a headset, or a sound card with its output looped into its input) or on two devices. Before this, the host kept a single UAC stream, and opening the second direction failed withhost_uac_open failed (-1).What changed.
usbif_host_uac.ckeeps one stream per direction instead of one in all. Each stream has its own transfers, ring and counters, and a transfer carries its stream in itscontext, so the callbacks never ask which one.host_uac_queued,_space,_capacity,_statsand_closetake the stream's endpoint address. Without one, they mean what they always did (close closes both), anduac_audiofalls back to that on firmware from before this change.UacHostInputgainsavailable().A fix found on the way. Closing a stream now sets the device back to alt 0.
usb_host_interface_release()sends no SET_INTERFACE, so until now a closed stream left the device streaming, and the next open's SET_INTERFACE changed nothing. It is skipped duringhost_stop()'s teardown, where no one would deliver the answer.On hardware. An ESP32-P4 panel hosting a full-speed USB-C headset dongle, its 3.5 mm output looped into its own mic through a splitter.
tests/hardware/uac_duplex_loopback.pykeeps both streams open for the whole run:The planted stall is the proof that the soak's zeros can fail. Before this change, on usbif main, the same dongle's capture opened, and opening its playback beside it failed with
-1.This dongle processes its mic. It sends capture only while playback is running: alone, every capture packet comes back empty. A 1 kHz sine loops back with a 1 ms period but the 3rd harmonic on top, with the fundamental 57 dB under it. 1.5 kHz comes back repeating every 2 ms, and quiet steady tones are suppressed. The stream itself is intact (packet for packet, byte for byte above), so the tone gate checks the waveform's period, and checks that spectral peaks land on harmonics of the tone, rather than asking for a clean sine. A stream at the wrong rate would still fail it.
Python tests: three new ones in
tests/test_usbif.py(output and input side by side, closing one leaves the other, older firmware still closes).