Граф коммитов

1057 Коммитов

Автор SHA1 Сообщение Дата
Andreas Pehrson 385f0ead74 Fix: Log the correct device id 2024-02-21 14:23:14 +01:00
Andreas Pehrson 5933a1edc7 Remove a redundant import to silence a warning
```
error: the item `atomic` is imported redundantly
  --> src/backend/mod.rs:35:5
   |
35 | use atomic;
   |     ^^^^^^
   |
  ::: src/lib.rs:6:1
   |
6  | extern crate atomic;
   | -------------------- the item `atomic` is already imported here
```
2024-02-21 14:23:14 +01:00
Andreas Pehrson 8ad010f07d Enable AGC by param
The Apple AGC has been observed to not amplify an overall low-volume
input signal (e.g. when the device has a volume control in hw). Perhaps
that is good enough for most cases. We'd rather make sure that if AGC is
requested we only apply one AGC algorithm, and if no AGC is requested we
do not apply any AGC algorithm.
2024-02-21 14:23:14 +01:00
Andreas Pehrson 0881dd16f2 Report AGC as a supported processing param 2024-02-15 10:36:09 +01:00
Andreas Pehrson d777208b31 Always enable AGC on VPIO 2024-02-13 15:09:58 +01:00
Andreas Pehrson ad16795a92 Always configure the output of VPIO for MONO
VPIO is inherently mono for both input and output.
2024-02-13 15:09:58 +01:00
Andreas Pehrson 4ba39ca14b Ignore input streams with kAudioStreamTerminalTypeUnknown
These show up on output-only devices when enabling (putting in your ear)
and disabling (putting into- and closing case) AirPods.
2024-01-18 14:22:48 +01:00
Andreas Pehrson a265c67d34 Move enabling of bypass later in VPIO creation
As tested on MacOS 14.0 toggling bypass on the fly won't be possible if
set too early during creation. Buggy.
2024-01-18 11:54:44 +01:00
Andreas Pehrson 164584aa07 Implement input mute and processing params APIs
This enables input muting when VPIO is used.
It also enables input processing of AEC+NS (only in combination) when VPIO is
used.
2024-01-18 11:54:44 +01:00
Andreas Pehrson 84d45a4954 Add input mute and processing interface tests 2024-01-18 11:54:44 +01:00
Andreas Pehrson bb9aa88cb8 Add input mute and processing commands to manual test_stream_tester 2024-01-18 11:54:44 +01:00
Andreas Pehrson 19b7a45769 Add a loopback mode to manual test_stream_tester 2024-01-18 11:54:44 +01:00
Andreas Pehrson a0534f6e91 Bump cubeb-backend to 0.12.0 and adapt ABI 2024-01-16 13:20:10 +01:00
Andreas Pehrson 89abc256a2 Fix an invalid_reference_casting warning in tests/parallel.rs
error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> src/backend/tests/parallel.rs:456:44
    |
456 |                     let context = unsafe { &mut *(context_ptr_value as *mut AudioUnitContext) };
    |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
    = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`
    = note: `#[deny(invalid_reference_casting)]` on by default
2023-12-19 20:57:07 +01:00
Andreas Pehrson 1f603cd9d4 Explicitly ignore INPUT_UNDEFINED input channels
Instead of allowing only explicitly recognized terminal types, this
patch makes INPUT_UNDEFINED explicitly ignored and everything else
allowed. Unrecognized terminal types will still be logged as before.

Background for this change is https://bugzilla.mozilla.org/show_bug.cgi?id=1870678
2023-12-19 20:57:07 +01:00
Andreas Pehrson 5fcea74fd2 Update cubeb-backend to 0.10.7 2023-12-12 19:05:23 +01:00
Andreas Pehrson ce3e2456f2 Update cubeb-backend and remove now-invalid comment 2023-12-12 14:08:31 +01:00
Andreas Pehrson d03c59ca2e Only use VPIO with stream pref VOICE for input
To avoid limiting non-voice duplex cases to MONO output, only use the
VPIO AudioUnit when the VOICE stream pref is specified for the input
stream.

This makes non-voice cases (in Firefox this is cases where getUserMedia
was called for audio with all processing constraints set to false)
susceptible to the "robotic voice" drift issue, but non-voice should be
a corner case, so impact is deemed low.
2023-12-12 14:08:31 +01:00
Andreas Pehrson 5d779af332 Avoid an unsigned integer underflow in the upmix path
If the number of stored frames is exactly the number of frames we are
pulling, we risk an underflow.
2023-12-08 23:18:09 +01:00
Andreas Pehrson 2a040b24aa Fix enumeration order and buffer handling in buffer manager
Range.enumerate() cannot go backwards, so with this patch we use a
forwards range instead, and reverse it.

Also, to ensure the upmixed audio fits in the internal buffer, this
patch ensures we resize it to the output format instead of the stored
format (pre-upmix).
2023-12-05 14:53:35 +01:00
Andreas Pehrson 406337f7b7 With voice processing, use the input sample rate for output
Makes the code match the intended behavior per the comment.
2023-12-05 10:19:26 +01:00
Andreas Pehrson 29f5326031 With voice processing, upmix the mono channel
This allows upmixing VPIO's mono input to the requested number of
channels. VPIO handles downmixing of the output side to mono.
2023-12-05 10:19:26 +01:00
Andreas Pehrson 978d38681a Add some stereo-input duplex stream tests 2023-12-05 10:19:26 +01:00
Andreas Pehrson d0810be039 Detect failures from all sanitizers 2023-11-23 15:02:21 +01:00
Andreas Pehrson 4733efda78 Don't duck the VPIO output device
With VPIO, all output streams other than the one of the VPIO AudioUnit
itself, on the VPIO output device, are ducked, i.e., their volume is
statically reduced.

From manual testing on MacOS 14 it seems creation of the VPIO AudioUnit
causes ducking of all output streams across all devices. After setting
the output device on the VPIO AudioUnit, ducking is automatically undone
on all output streams except for those on the VPIO output device.
On MacOS 10.15, system logs show the same ducking on creation, and an
additional ducking being applied when initializing the VPIO AudioUnit.

With no control surface to control ducking for now, manually undo it on
the VPIO output device after the VPIO AudioUnit has been initialized.
2023-11-23 13:25:56 +01:00
Paul Adenot a90aa5bcab Assert when forgetting to unregister device collection callbacks on context destruction should be fatal in release 2023-11-22 10:10:47 +01:00
Paul Adenot 347af0022f Remove unused tests 2023-11-22 10:10:47 +01:00
Paul Adenot 49a0c42094 Remove current broken implementation of current_device() 2023-11-21 18:02:32 +01:00
Paul Adenot cb373b8c42 Destroying a context with collection change callbacks not removed should crash
54217bca3f/test/test_duplex.cpp (L204-L223) tests this.
2023-11-21 14:59:17 +01:00
Andreas Pehrson 964e14628f Remove output channel count restriction
The cubeb API must not put a restriction on the output stream's channel
count. This is also ensured by the cubeb repo's gtests. This commit
adds an equivalent of the stream_init bit of the relevant test there,
to cubeb-coreaudio-rs.
2023-11-20 15:27:09 +01:00
Andreas Pehrson ef2f810e6b Run test_suspend_duplex_stream_by_unplugging_a_nondefault_input_device
test_suspend_duplex_stream_by_unplugging_a_nondefault_input_device has
been around a while but wasn't run because it was marked with #[ignore].
It seems like the intention was that it should run, so this patch
enables it.
2023-11-16 19:22:36 +01:00
Andreas Pehrson 222624fa9e Remove redundant is_aggregate_device
The only caller is filtering out aggregate devices from a collection
that has already filtered out aggregate devices.
2023-11-16 19:22:36 +01:00
Andreas Pehrson a5a43b6935 Override audio unit stream format's mChannelsPerFrame
Tap streams can create additional input streams on devices, leading
to higher-than-expected channels on the audio unit stream format. Use
the already filtered get_channel_count instead.
2023-11-16 19:22:36 +01:00
Andreas Pehrson a30d09795b With vpio, query a dedicated audio unit for channel layout
The VoiceProcessingIO audio unit cannot return the channel layout
for its output device. With this patch, in case we are using vpio,
we try to use a dedicated AudioUnit for the output device and query
that, like we would have queried the regular output unit.
2023-11-16 19:22:36 +01:00
Andreas Pehrson dc4dac9ce6 Don't account for channels on Tap input streams
With VPIO, output devices may get a Tap stream, basically adding an
input AudioStream to the output device. To avoid enumerating
output-only devices as input devices, we ignore these channels.
2023-11-16 19:22:36 +01:00
Andreas Pehrson 8d83a4385f Always try a VoiceProcessingIO AudioUnit
The drift correction provided by aggregate devices has proven unreliable
as a usb input paired with builtin or connected analog speakers often
underruns within a few minutes, depending on clock drift.

The VoiceProcessingIO AudioUnit handles drift properly.
This patch will try to set up the VoiceProcessingIO AudioUnit whenever
we're in duplex. This patch also sets up a failover path so that if setting up
the VoiceProcessingIO AudioUnit fails, we try an aggregate device or a plain
AudioUnit, in that order.

For now, always in bypass mode, as we don't yet have an api to toggle
audio processing features dynamically. Note that the VoiceProcessingIO
AudioUnit will implicitly enable audio ducking in the platform.
2023-11-16 19:22:36 +01:00
Andreas Pehrson e546c3359b Reject stream_init with no stream params or no data callback
This patch is needed because of a race where some tests init a stream
with a null data callback and immediately destroy the stream. With VPIO
a race is triggered where sometimes there would occur a data callback.
The resampler however, cannot handle a null data callback, so it crashes
on a nullptr deref.

This patch also rejects stream_init when no stream parameters are passed
in, and adjusts tests to exercise all these code paths.
2023-11-16 19:22:36 +01:00
Andreas Pehrson b0ec20f9c1 Clarify the reason for invalid parameter errors in stream_init 2023-11-16 19:22:36 +01:00
Andreas Pehrson b4e0624cfe Dispose created AudioUnits on failure
Dropping an AudioUnit from the stack does not guarantee its disposal.
This patch disposes AudioUnits that are about to be dropped explicitly.
2023-11-16 19:22:36 +01:00
Andreas Pehrson c3c8b14c02 In get_channel_count enumerate streams directly
This commit does not change behavior of get_channel_count. But it
changes it from counting channels on a device's stream configuration,
which is essentially a list of stream descriptions, to counting channels
by enumerating streams and querying them for their format. This will
help filter out Tap input streams from output devices in a future
commit.
2023-11-14 11:14:45 +01:00
Andreas Pehrson fbd6e0f718 Fix get_stream_latency as streams have only the global scope
Per CoreAudio/AudioHardwareBase.h:
> AudioStream is a subclass of AudioObject and has only the single scope,
> kAudioObjectPropertyScopeGlobal. They have a main element and an element for
> each channel in the stream numbered upward from 1.
2023-11-14 11:14:45 +01:00
Andreas Pehrson 9b8de33f09 In test_get_device_streams, assert that we found some streams 2023-11-14 11:14:45 +01:00
Andreas Pehrson 7b2c658e30 Assert that stream operations are done on the queue
To mitigate potential race conditions in the platform, make sure all
stream-specific operations are done on the stream's serial queue.
2023-11-14 10:35:02 +01:00
Andreas Pehrson b539f9ac89 Enable TSAN
With operations now serialized per-context, let's try to enable TSAN.

Fixes #129.
2023-11-14 10:35:02 +01:00
Andreas Pehrson 04a05cc585 Fix a race condition in the output callback
The output callback reads self.input_unit, whereas close() writes
self.input_unit before stopping the output unit (and its callback).

This commit defers any write operations on self's unit members until
both units have been stopped.
2023-11-14 10:35:02 +01:00
Andreas Pehrson 1a9cce25ba Improve device-change tests to avoid sleeps
Some device-change tests are prone to intermittents as they rely on
waiting for async events by sleeping the current thread for some
arbitrary time.

This patch rewrites Watcher<T> and friends to use a Mutex and a Condvar
instead of an atomic. The new pattern is that the signaling bit of the
code, typically a callback, grabs the mutex, changes some state and
notifies the test thread through the condvar. This means the test thread
can block on the mutex, and wait on the condvar as needed. The watcher
uses existing condvar functions to support waiting until a predicate is
no longer true, and doing the same thing with a timeout. One has to be
wary of deadlocks, but this is test-only non-critical code so generally
speaking fine.
2023-11-14 10:35:02 +01:00
Andreas Pehrson 0cd9e4860c Make TestDeviceSwitcher skip over devices that cannot be made default
Without this patch if we try to make a device the default input device,
while that does not have an effect, we'll hang waiting for a
device-change event that never comes.

This is possible because with VPIO and Taps there is no fully
deterministic way to determine what is a valid input device.
2023-11-14 10:35:02 +01:00
Andreas Pehrson db0387fd34 Monitor liveness of explicitly chosen output devices 2023-11-13 15:14:24 +01:00
Andreas Pehrson 9c2ccd142a Use match instead of if-else to unpack ptr from Option
This silences a warning on nightly rustc
2023-11-13 15:14:24 +01:00
Andreas Pehrson a3e5f529a5 Make aggregate device used for tests NON-PRIVATE
Testing locally on MacOS 14 there appears to be no devicechange events
when the pluggable (aggregate) device used for tests is private.

It seems logical that there are no devicechange events for a device that
does not get exposed to other apps, and the app that created/destroyed
it should know that it did, indeed, create or destroy it.
2023-11-13 15:14:24 +01:00