* Revise destroy_cubeb_device_info
* Move destroy_cubeb_device_info tests
`destroy_cubeb_device_info` is checked in the tests calling
`create_cubeb_device_info`. We only need to confirm the `friendly_name`
is set when calling `destroy_cubeb_device_info`
* Bail out if 'cargo fmt' fails
* Bail out if 'cargo clippy' fails
* Move install_rustfmt_clippy.sh from before script to install
* Use loose pattern for nightly toolchain
The name of the nightly toolchain on Travis server is `nightly
(default)` instead of `night-*`.
* Add useful logging statements
* Avoid having a long input buffer if we're not using an aggregate device
This lowers the input latency: it's unnecessary to keep old data around,
we want to most current data, with a safety margin.
* Pass the correct number in minimum_resampling_input_frames
The current code makes no sense.
* Create a friendly wrapper around dispatch_queue_t
Instead of using low-level dispatch APIs directly, we should create a
wrapper around `dispatch_queue_t` that can retain or release the
reference count automatically.
* Hide low-level dispatch APIs
With the new `Queue` struct is introduced, there is no need to expose
the low-level dispatch APIs. Those low-level dispatch APIs should be
prevented from being used directly.
* Make the task queue stream-local
The stream start, stop, destroy, reinit tasks, from different streams,
will be dispatched to the same task queue and then be executed one by
one. In fact, those tasks dispatched from different streams can be run
separately in parallel since those tasks don't share data in common. We
can create a task queue per stream and dispatch the stream's own task to
its own task queue so those tasks fired from different streams can be
run in parallel. This should boost the speed of creating, staring,
stopping, or reinitializing multiple streams at the same time.
* Implement a sync task runner that runs the final task
Any task appended after the stream-destroy task should be cancelled.
After moving the task queue from being owned by the cubeb context to the
cubeb stream, we can easily cancel the stream X's job in the task queue
after stream X is destroyed, without interfering other stream's tasks.
* Give task queue an unique label
The task queue in the cubeb stream should have a unique lable so it
would be easier to identify the task queue's owner when debugging
issues.
* Merge create_dispatch_queue to Queue::new
* Merge release_dispatch_queue to Queue::drop
* Merge retain_dispatch_queue to Queue::clone
* Merge get_dispatch_context to Queue::get_context
* Merge set_dispatch_context to Queue::set_context
* Init should_cancel to false in new instead of run_final
* Replace generic type by AtomicBool type in {get, set}_context
* Rename {get,set}_context to {get,set}_should_cancel
* Merge async_dispatch to run_async
* Merge sync_dispatch to Queue::run_{sync, final}
* Move create_closure_and_executor into Queue
* Destroy AudioUnitContext properly
* Revise comments
* Isolate the device-changed tests
Sometimes we need to run the device-changed test quickly, without
running the regular tests. Isolate the device-changed tests can help
programmers to debug the device-related issues without commenting the
scripts in run_tests.sh.
* Respect default RUST_BACKTRACE setting
* Add instructions for device-tests usage
* Add instructions for stream tester usage
* Fix typo
* Remove the duplicate sanitizer tests
Since the tests in the sub crates will be run in run_tests.sh and the
run_tests.sh will be executed by the sanitizers, the tests in the sub
crates will be executed by the sanitizers with the command
`RUSTFLAGS="-Z sanitizer=*" sh run_tests.sh`. That is, running the tests
in under sub crate by `RUSTFLAGS="-Z sanitizer=*" cargo test` is
duplicate work.
* Simplify run_sanitizers.sh
* Reuse the compiling when building the sub crate
The run_tests.sh should use `cargo * -p <SUB_CRATE>` if it's possible.
By doing so, the compiling for <SUB_CRATE> can be reused when building
the main crate. It will save plenty of compiling time, especially when
compiling this crate for the sanitizers.
* Run the tests in the sub crate
* Run tests in sub crate by the sanitizers
* Add format and lint(clippy) checks in run_tests.sh
The format check should always be run, in main crate and sub crate, not
only in Travis CI server only. The format checks and lints(clippy)
checks should be moved from .travis.yml to run_tests.sh.
* Set RUST_BACKTRACE in the environment
* Add Rust format check in Travis CI
* Add Rust clippy check in Travis CI
* Fix warning: array_into_iter
Replace `.into_iter()` by `.iter()` used in the Rust array
* Fix warning: private_in_public
Allow private struct AudioUnitStream in public interface when running tests
* Fix clippy errors in audio_unit_get_property_info
* Fix clippy errors in audio_unit_render
* Align interface of audio_unit_get_property with audio_unit_get_property_info
- Change `data` and `size` of audio_unit_get_property from raw pointers
to references
- Make the variable `size` used when calling audio_unit_get_property in
test_audiounit_scope_is_enabled live when the calling explicitly
* Align interface of audio_unit_set_property with audio_unit_get_property's one
* Fix clippy warning: redundant_field_names in create_device_info
* Fix clippy warning: let_and_return in create_blank_device
* Fix clippy warning: let_and_return in audiounit_input_callback
* Fix clippy warning: needless_return in host_time_to_ns
* Fix clippy warning: or_fun_call in get_device_label
The function within `or(...)` will always be called and potentially
allocate an object acting as the default. We don't need to call
get_device_name if get_device_source_name works
* Fix clippy warning: len_zero in Mixer::new
* Fix clippy warning: option_map_unit_fn in Finalizer::drop
* Fix clippy error: float_cmp in minimum_resampling_input_frames
* Fix clippy warning: needless_range_loop in audiounit_output_callback
* Allow clippy::mutex_atomic on set_buffer_size_sync
* Fix clippy warning: redundant_clone in get_range_of_sample_rates
* Fix clippy warning: cmp_null in DevicesData::is_empty
* Fix clippy warning: unnecessary_unwrap in reinit
* Fix clippy warning: or_fun_call in current_device
* Allow clippy::cognitive_complexity on CoreStreamData::setup
* Allow clippy::cast_ptr_alignment on get_device_stream_configuration
* Fix clippy warning: needless_range_loop in get_default_channel_order
* Fix clippy warning: missing_safety_doc for audiounit_rust_init
* Avoid using set_len in allocate_array
`set_len` is unsafe function that should be avoided if possible. On the
other hand, we should initialize the item value when allocating the
array by expected size or the number of the items.
* Fix warning: unused_parens in stream_init
* Fix warning: unused_parens in CoreStreamData::setup
* Skip test changing the default device if no device is available
* Automatically install latest clippy and rustfmt
- Download and install the latest available rustfmt if rustfmt isn't
available in the nightly
- Install latest available clippy if clippy in nightly isn't available
* Bail out if the output device has no output channel
* Log the device info in use
The device info will be set when the stream is initialized or reset when
the stream is reinitialized. Logging the device info helps to debug
issues, when calling underlying system APIs raise errors.
`Atomic*::get_mut()` uses `UnsafeCell` to mutate the value directly, so `Atomic*::get_mut()` is only safe if it's called from a single thread. If `Atomic*::get_mut()` is called from multiple threads, or `Atomic*` is accessible as mutable references in different threads, it will cause the data race.
Thus, for all the `Atomic*` in the current code, the `*.get_mut()` should be replaced by `*.store()` to avoid the data race. This change will solve the data race found by ThreadSanitizer(#34).
* Replace all shutdown.get_mut() to shutdown.store()
* Replace all switching_device.get_mut() to switching_device.store()
* Replace all reinit_pending.get_mut() to reinit_pending.store()
* Replace all draining.get_mut() to draining.store()
* Replace all destroy_pending.get_mut() to destroy_pending.store()
- Add a script to run test suits by all the available sanitizers
- Add an instruction of running sanitizers in _README.md_
- Run the sanitizers on _Travis CI_ but the tests are allowed to fail
- Since sanitizers are under development, they may false positives, or be unavailable for Nightly toolchain sometimes
* Update audio-mixer to 0.1.2
By ChunMinChang/audio-mixer#1, the audio mixer would be created by
`&[Channel]` instead of `Vec<Channel>`. Update the mixer to match the
changes.
* Use void type for mix buffer to avoid clippy errors
* Add a test checking if the created aggregate device is not in the list
When creating the duplex stream, it's very likely to create an aggrgate
device as well. The aggregate device created is for internal usage so it
shouldn't be exposed to the device list.
* Correct the removal of the aggregate device in the device list
The `PRIVATE_AGGREGATE_DEVICE_NAME` is just part of the `uid` of the
created aggregate device, so we should check if the `uid` contains that
string rather than comparing them.
The function calls in the `debug_assert!` will be ignored in release
build. As a result, the function call inside won't be executed. We
should not call functions in the `debug_assert!`. We should probably
not call functions in `assert!` either since the `assert!` may be
changed to `debug_assert!` someday.
* Create an oxidized mixer
Create an oxidized cubeb-mixer, which is adapted from cubeb_mixer.cpp,
as the new mixer module. The new mixer is able to mix from any input
channels to any output channels, without predefined channel order.
The old cubeb-mixer has a strict rule for channel order. For example,
for an stereo layout, it must be 2-channel. One is front-left, the other
is front-right. And the order of the channels must be [front-left,
front-right]. However, in MacOS, the N-channel output device can actually
be set to an 1-to-N output device with any channel order. For example,
the 6-channel output device can be set as a stereo with channel order:
[unused, unused, front-left, unsued, front-right, unused], where the
unused channel should be silience.
With the new mixer, the restriction of the channel order would be loosen
and audio is able to be mixed from any channel layout to any channel
layout, without any pre-defined channel order and limitation of
channels' number.
* Move special setting from mod.rs to mixer.rs
The output audio layout would be forced to mono or stereo when output
channel count is 1 or 2. We should put this special handling in mixer.rs
rather than mod.rs so all the special setting or error handling could be
in the same place.
* Allow cubeb stream's output layout to be CUBEB_LAYOUT_UNDEFINED
* Correct test cases
* Remove deoendency of cubeb_backend::ChannelLayout in mod.rs
With the new mixer, we don't rely on cubeb_backend::ChannelLayout in
mod.rs anymore. The cubeb_backend::ChannelLayout would be used in
mixer.rs instead.
* Add debugging logs
This log would expose the user's output device settings and the stream
settings that would be mixed. It would help us to understand the user's
device setting when they report mixing-related bug.
* fix typo
* revise comments
* Expose channel info from mixer
* Remove unnecessary clone
* Remove unnecessary comments
* Correct typo
* Replace hardcode by bit-shifted value
* Use criterion crate for benchmark
- Introduce criterion
- Create benchmark tests
* Remove todo
* Apply mixer::Channel::count() to set the total channels in CHANNEL_OERDER
Calling audiounit_get_current_channel_layout by input-only
(microphone-only) AudioUnit is prone to cause crashes intermittently.
The test_set_channel_layout_input is likely to cause intermittent crashes
since it calls audiounit_get_current_channel_layout by a input-only
AudioUnit. Removing this test can avoid the random crashes when running
`cargo test` (#31).
The cubeb implementation has no need to get the channel-layout on input
side, so the test_set_channel_layout_input is unnecessary anyway.
* Remove todo-tests
* Print devices when DeviceSwitcher is created
* Speed up the device switching
The index of the current device will be calculated again and again when
the DeviceSwitcher switch the device to next candidate. We could keep
tracking the index instead of calculating it each time when switching
device. The drawback is that the DeviceSwitcher will become mutable but
it's fine since it's only used in the tests.
* Print devices before switching them
* Print the devices in TestDeviceSwitcher internaly
The test_ops_stream_register_device_changed_callback is disabled before
since stream_register_device_changed_callback ins't implemented in
cubeb-rs's capi_new macro. Howeverm it's already fixed in
https://github.com/djg/cubeb-rs/pull/36 so this test is able to be
turned on.
* Allow get_range_of_sample_rates returns empty range
The ranges returned from get_ranges_of_device_sample_rate may be an
empty vector and then the assertion checking the ranges is not empty
will be hit. We should allow to return the empty ranges in
get_range_of_sample_rates since it's possible.
* Simplify return type of get_range_of_sample_rates
In the previous change, the assertion to check if the list of the
available ranges is removed and the empty list is allowed to be
returned. However, the empty list will be treated as an error in our
usage. In that case, we could just return error result when the list is
empty. That will simplify the API usage.
* Start AudioUnit in serial queue
The stream-start and stream-reinit may run in parallel and cause a
racing issue: The stream data callback may still run while the stream is
being reinitialized. Running stream-start in the same task queue where
the reinit task is could solve this racing issue.
* Stop AudioUnit in serial queue
The stream-stop and stream-reinit may run in parallel and causes a
racing issue: The stream-stop may executed before stream-restart in
reinit so the stream-stop fails silently. Running stream-stop in the
same task queue where reinit task is could solve this racing issue.
* Stop data-callback in serial queue when destorying stream
The stream-start and stream-destroy may run in parallel and cause a
racing issue: The data-callback may still be run while the stream is
being destroyed. The stream-stop in destroy fails silently in this case.
Moving stream-stop in the task queue where the stream-destroy and
stream-start are, beforing doing stream destroy task, could solve this
racing issue.
* Assert the timing for start AudioUnit
An an assertion to make sure the stream start is only allowed to be
called after the stream is initialized and before the stream is
destroyed.
* Rename variables
* Remove unnecessary mutex
The clone of the mutex that will be passed into sync_dispatch is not
really needed. Those data in the mutexes won't be operated in the same
time since the code after sync_dispatch won't be executed before the task
dispatched by sync_dispatched are finished. Hence, mutex around the data
that will be operated by the code in sync_dispatched can be omitted.
* Log state in state callback
* Move STREAM_FORMAT to the function using it
* Add a test template with default callbacks
* Revise comments
* Add manual tests: Loop in input/output/duplex streams
* Remove unnecessary type declarations
* Set RUST_BACKTRACE in test script
* Move common test code to tests/utils.rs
* Fix type
* Terminate stream by pressing q
* Create a stream tester with common testing operations
* Add a choice to quit early
* Revise stream tester
To add the command to create or destroy the stream, the cubeb context
need to be passed to the test function. Instead of using the test
template that will pass the cubeb stream, using the test template that
will give te cubeb context is the right way to create the test.
* Revise command line interface