I am using a Raspberry Pi 3B+ as the USB host for an embedded device that I have configured to appear as a USB Audio 2.0 compliant microphone.
I am currently using PyAudio for opening and recording the audio stream. For testing purposes, the embedded device only transmits a sinusoidal signal, with 1 period of the signal corresponding to 1024 samples. Since the device is configured to be a mono-channel microphone with 8-bit PCM audio, the sinusoidal signal period occupies 1024 bytes.
This is equivalent to the maximum packet size for an Isochronous Endpoint's (micro)frame in USB 2.0 High-Speed. I have configured my embedded audio device for bInterval=1, which corresponds to support for a polling interval of 125 μs with 1024 bytes to be sent in each microframe when it receives the IN token request from the host. The audio device and the application (PyAudio) are both configured for an audio sampling frequency of 48 KHz.
However, when I observe the recorded stream, I can see that there is a gap in audio after every complete period i.e. after transmission of 1024 bytes. Zooming in, it can be observed that each gap is roughly about 1 ms in duration. This would correspond to a polling interval for a frame for USB-FS which should not be the case since the RPi 3 B+ supports USB 2.0 High-speed.
When the Audio device (my programmable embedded device) is configured to bInterval=4, hence polling interval of 1 ms, there is no issue with the recorded audio and no gap is observed after transmission of 1024 bytes (1 complete wave period). There appears to be no syncing issues between the audio application (PyAudio) and hardware (USB controller) within the USB host (RPi) since PyAudio after reading the device descriptor would expect each successive 1024 bytes to arrive after 1 ms.
So why is the RPi 3B+'s USB controller unable to issue Isochronous IN tokens every 125 μs? Is this an issue with PyAudio and the underlying PortAudio library? Can it not support such fast polls or token issues? Is this an issue with the ALSA HAL and overhead of other processes running on the Raspberry Pi that add latency?
Please note that I am open to suggestions or feedback from people who have implemented high speed USB audio streaming using libraries and frameworks other than PyAudio. I am not restricted to using only that.