Add clear documentation that this is a fork with Pa_RefreshDevice functionality,
link to the specific commit, and provide instructions for using with the nodeaudio
Node.js bindings.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The currently used clock, CLOCK_REALTIME, will have discontinuous jumps, forward
and backward, when the system clock is adjusted. This is bad for synchronizing
audio. CLOCK_MONOTONIC does not have jumps, and never moves backward, but does
have the continuous adjustments done by NTP to increase clock accuracy.
Since kernel 2.6.25 ALSA has use CLOCK_MONOTONIC by default for timestamps
(commit b751eef1 from Dec 13 2007). This change means the timestamps provided
in the PA callbacks can be compared to PaUtil_GetTime(), which currently does
not work.
The function used on MacOS, mach_absolute_time(), behaves like CLOCK_MONOTONIC.
If the system does not have CLOCK_MONOTONIC, fallback to CLOCK_REALTIME, which
is what alsa-lib does for such systems. Which at this point would need to be
very old.
* Use clock monotonic for condition variable
This is necessary to match PaUtil_GetTime() also using the monotonic
clock. Otherwise the wait time, derived from that function, will be
completely incorrect.
This will also fix an obscure flaw if the system clock is adjust while
waiting for the stream to open, it might not wait at all and fail or
wait (effectively) forever instead of timing out, depend on the
adjustment direction.
On ALSA the StreamTime was not advancing so the while()
loop never exited. Now it will time out if it plays for much
longer than expected without the stream time changing.
Also measure timestamp latency from callback info.
ALSA added nanosecond timestamps in library version 0.9.1. Use these
instead of microsecond timestamps for reporting audio timestamps as well
as underrun/overrun times.
alsa-lib version 0.9.1 was released on Mar 11 2003. I had fallback code
to use non-hires timestamps, but after 18 years it didn't seem
necessary, and I removed it from this commit.
Avoid compiler warning suggesting the buffer is too small:
../PortAudioLib/portaudio/src/hostapi/alsa/pa_linux_alsa.c: In function 'BuildDeviceList.constprop':
../PortAudioLib/portaudio/src/hostapi/alsa/pa_linux_alsa.c:1304:45: warning: '%s' directive output may be truncated writing up to 49 bytes into a region of size between 46 and 50 [-Wformat-truncation=]
snprintf( buf, sizeof (buf), "%s%s,%d", hwPrefix, alsaCardName, devIdx );
^~ ~~~~~~~~~~~~
../PortAudioLib/portaudio/src/hostapi/alsa/pa_linux_alsa.c:1304:42: note: directive argument in the range [0, 2147483647]
snprintf( buf, sizeof (buf), "%s%s,%d", hwPrefix, alsaCardName, devIdx );
^~~~~~~~~
../PortAudioLib/portaudio/src/hostapi/alsa/pa_linux_alsa.c:1304:13: note: 'snprintf' output between 3 and 65 bytes into a destination of size 50
snprintf( buf, sizeof (buf), "%s%s,%d", hwPrefix, alsaCardName, devIdx );
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This patch fixes a problem caused by special regex characters
appearing in the device names when using the Jack interface to PipeWire.
It is uncommon for JACK ports to have any characters that need to
be escaped in a regex. jackd simply calls the audio interface
"system". However PipeWire uses the device name from ALSA for the
JACK port names. If this contains any special regex characters,
BuildDeviceList would find the device but determine it has 0
input channels and 0 output channels. In my case, I have an RME
Babyface Pro which puts its serial number in parentheses:
$ aplay -l
card 0: Pro70785713 [Babyface Pro (70785713)], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
* Clean up whitespace in src/hostapi/coreaudio in preparation for .editorconfig. Convert tabs to 4 spaces. Indent by 4 spaces. Strip trailing whitespace. Ensure only one EOL at EOF.