The lifetime of the stream is guaranteed to outlive any items running on the
serial queue. This is ensured by stream destroy flushing the serial queue
before freeing stream resources.
Avoids a possible deadlock inside CoreAudio if another thread calls
AudioOutputUnitStop concurrently. The thread running the render callback holds
the HALB_Mutex and blocks acquiring the CAMutex inside AudioOutputUnitStop.
The racing thread calling AudioOutputUnitStop holds the CAMutex and blocks
acquiring the HALB_Mutex.
This uses an spsc ring buffer to proxy the audio input callback
parameters to the output thread, for logging purposes.
Without this, multiple threads can attempt writing in the spsc ring
buffer that's used for logging, which make an assertion blow up.
* Revert 8c1c57a, keeping the changes in 8b7d464
* Really attempt to create a device_info when reiniting to ensure a valid device is availble.
* Let the OS error out and propagate the error instead of asserting
* Revert "Let the OS error out and propagate the error instead of asserting"
This reverts commit a5fe4208cc.
* Revert "Really attempt to create a device_info when reiniting to ensure a valid device is availble."
This reverts commit 38896988d7.
* Revert "Revert 8c1c57a, keeping the changes in 8b7d464"
This reverts commit 0a82ab619f.
* Fix device reinit when no input/output device are present
Co-authored-by: Chun-Min Chang <chun.m.chang@gmail.com>
* Use get_channel_count for max_channel_count
We use `get_channel_count` for the max channel count in
`enumerate_devices` but we use `get_device_stream_format`'s channel info
for `max_channel_count`. We should use `get_channel_count` instead.
* Return OSStatus as error in get_channel_count
No need to return cubeb-error in non top-level API.
* Shorten the function name
Rename `audiounit_get_default_device_id` to `get_default_device_id`.
* Return error for default device if it's kAudioObjectUnknown
The default output device on CircleCI server is `kAudioObjectUnknown`.
We should return error if we get this kind of device since all its
operations will be invalid.
* Add todo
Remove input_channels_to_ignore from CoreStreamData, and pass it
directly to the BufferManager.
Refactor input_desc so that it's always what we set the input audiounit
to, and subsequently remove input_hw_rate, because it's redundant with
input_desc.mSamplerate.
We don't want to use the regular mixer here, we can do everything in
place, always, and make it very efficient. Also it's specialized and
only handles very few cases.
When using an aggregate device, it can be that the output device has
input channels. Those input channels are delivered in the input callback
as usual, in the same buffer as the input channels of the input device
we care about. The channels for the output device are _always_ first in
the buffer, followed by the channels for the inpuut device, because of
the way the aggregate device is setup (see aggregate_device.rs).
This patch allows remixing the data, dropping the channels we don't want
and putting the frames for the channels the user wants at the right
location in the buffer.
We always monitor the default input changed event even if we don't use
the default input device. As a result, one audio stream has an input can
be re-initialized even if its device has no change at all (e.g., When
default input device is X and the input stream S uses device Y as its
input device, the S will be re-initialized if the system default device
is changed from X to Z, where X, Y, Z are all different devices.).
To avoid the above problem, and not to reinitialize the stream, when it
has input, we should monitor the default-input change only when the user
requests to follow the system default input.