cubeb-coreaudio-rs/README.md

141 строка
5.6 KiB
Markdown
Исходник Обычный вид История

2018-09-10 21:18:00 +03:00
# cubeb-coreaudio-rs
[![CircleCI](https://circleci.com/gh/mozilla/cubeb-coreaudio-rs.svg?style=svg)](https://circleci.com/gh/mozilla/cubeb-coreaudio-rs)
2021-03-10 08:11:38 +03:00
[![Build & Test](https://github.com/mozilla/cubeb-coreaudio-rs/actions/workflows/test.yml/badge.svg)](https://github.com/mozilla/cubeb-coreaudio-rs/actions/workflows/test.yml)
2019-03-25 21:21:01 +03:00
2019-07-22 22:37:14 +03:00
*Rust* implementation of [Cubeb][cubeb] on [the MacOS platform][cubeb-au].
2018-09-10 21:20:11 +03:00
2018-10-08 01:58:11 +03:00
## Current Goals
2019-08-20 01:05:32 +03:00
- Keep refactoring the implementation until it looks rusty! (it's translated from C at first.)
2020-04-20 06:24:55 +03:00
- Check the [todo list][todo]
2019-02-19 21:23:12 +03:00
2019-01-11 04:33:06 +03:00
## Status
2019-02-14 02:36:49 +03:00
2020-04-20 06:24:55 +03:00
This is now the _Firefox_'s default audio backend on *Mac OS*.
2019-05-20 21:13:39 +03:00
2020-10-30 03:45:19 +03:00
## Install
### Install cubeb-coreaudio within cubeb
Run the following command:
```sh
curl https://raw.githubusercontent.com/mozilla/cubeb-coreaudio-rs/trailblazer/build-audiounit-rust-in-cubeb.sh | sh
2020-10-30 03:45:19 +03:00
```
### Other
Just clone this repo
2019-04-04 00:49:46 +03:00
## Test
2019-04-04 00:49:46 +03:00
Please run `sh run_tests.sh`.
Some tests cannot be run in parallel.
They may operate the same device at the same time,
or indirectly fire some system events that are listened by some tests.
2019-04-04 01:11:49 +03:00
The tests that may affect others are marked `#[ignore]`.
They will be run by `cargo test ... -- --ignored ...`
after finishing normal tests.
Most of the tests are executed in `run_tests.sh`.
2019-04-04 00:49:46 +03:00
Only those tests commented with *FIXIT* are left.
2019-02-26 22:12:06 +03:00
### Git Hooks
You can install _git hooks_ by running `install_git_hook.sh`.
Then _pre-push_ script will be run and do the `cargo fmt` and `cargo clippy` check
before the commits are pushed to remote.
### Run Sanitizers
Run _AddressSanitizer (ASan), LeakSanitizer (LSan), MemorySanitizer (MSan), ThreadSanitizer (TSan)_
by `sh run_sanitizers.sh`.
The above command will run all the test suits in *run_tests.sh* by all the available _sanitizers_.
However, it takes a long time for finshing the tests.
### Device Tests
Run `run_device_tests.sh`.
If you'd like to run all the device tests with sanitizers,
use `RUSTFLAGS="-Z sanitizer=<SAN>" sh run_device_tests.sh`
with valid `<SAN>` such as `address` or `thread`.
#### Device Switching
2019-05-09 19:12:06 +03:00
The system default device will be changed during our tests.
All the available devices will take turns being the system default device.
However, after finishing the tests, the default device will be set to the original one.
The sounds in the tests should be able to continue whatever the system default device is.
#### Device Plugging/Unplugging
2019-05-09 19:12:06 +03:00
We implement APIs simulating plugging or unplugging a device
by adding or removing an aggregate device programmatically.
It's used to verify our callbacks for minitoring the system devices work.
2019-04-04 01:11:49 +03:00
### Manual Test
2019-04-04 01:11:49 +03:00
- Output devices switching
2019-04-05 00:48:19 +03:00
- `$ cargo test test_switch_output_device -- --ignored --nocapture`
- Enter `s` to switch output devices
- Enter `q` to finish test
- Device collection change
- `cargo test test_device_collection_change -- --ignored --nocapture`
2019-04-05 00:48:19 +03:00
- Plug/Unplug devices to see events log.
- Manual Stream Tester
- `cargo test test_stream_tester -- --ignored --nocapture`
- `c` to create a stream
- `d` to destroy a stream
- `s` to start the created stream
- `t` to stop the created stream
BMO 1692910: Avoid the race between `set_volume` and stream-reinitialization (#122) * Manual test: Add a command to set stream volume * Test case - `assertion failed: !unit.is_null()` in `set_volume` The following commit message demonstrating a possible cause of the assertion-failed issue in [BMO 1692910](https://bugzilla.mozilla.org/show_bug.cgi?id=1692910) This is a data-racing issue. The assertion will be hit when the 1. `set_volume` is called on thread A at the same time when the stream is being reinitialized at thread B 2. `set_volume` is called on thread A just after the `self.core_stream_data.close()` is called on the thread B, which will uninitialize and dispose the AudioUnit called in `set_volume` on thread A This commit adds some delay to give us a room to call the `AudioUnitStream.set_volume` in the manual test, `test_stream_tester`, after the `AudioUnitStream.stream.core_stream_data.close()` is called when the `AudioUnitStream` is being reinitialized The following log illustrates the steps to hit that assertion in `AudioUnitStream.set_volume` on purpose: ``` % cargo test test_stream_tester -- --ignored --nocapture Compiling cubeb-coreaudio v0.1.0 (/Users/cchang/Work/cubeb-coreaudio-rs) Finished test [unoptimized + debuginfo] target(s) in 3.24s Running target/debug/deps/cubeb_coreaudio-29d6ac8d8020965d running 1 test commands: 'q': quit 'c': create a stream 'd': destroy a stream 's': start the created stream 't': stop the created stream 'r': register a device changed callback 'v': set volume c Select stream type: 1) Input 2) Output 3) In-Out Duplex 4) Back 2 Stream 0x7f86967160f0 created. commands: 'q': quit 'c': create a stream 'd': destroy a stream 's': start the created stream 't': stop the created stream 'r': register a device changed callback 'v': set volume s state: Started Stream 0x7f86967160f0 started. commands: 'q': quit 'c': create a stream 'd': destroy a stream 's': start the created stream 't': stop the created stream 'r': register a device changed callback 'v': set volume ******************************************************************* * Switch the audio device here to trigger stream reinitializatoin * ******************************************************************* 1 Reinit > Sleep for 5s v thread 'backend::tests::manual::test_stream_tester' panicked at 'assertion failed: !unit.is_null()', src/backend/mod.rs:268:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace test backend::tests::manual::test_stream_tester ... FAILED failures: failures: backend::tests::manual::test_stream_tester test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 182 filtered out ``` * Move `set_volume` to the task-queue running stream reinitialization One simple way to avoid the data-racing issue mentioned in the previous commit is to dispatch the `set_volume` task to the same task-queue that runs the stream reinitialization tasks (it executes the stream destroying task as well). That is, if `set_volume` task is executed before stream reinitialization, the volume will be set before the stream is reinitialized. If the `set_volume` task is executed after stream reinitialization, the volume will be set after the stream finishes its reinitialization task. * Revert "Test case - `assertion failed: !unit.is_null()` in `set_volume`" This reverts commit 8c1e3f91bd05643113d00ba93c965711f5ac3c10. * Update README
2021-02-23 22:26:28 +03:00
- `r` to register a device changed callback to the created stream
- `v` to set volume to the created stream
- `q` to quit the test
- It's useful to simulate the stream bahavior to reproduce the bug we found,
with some modified code.
2019-04-04 01:11:49 +03:00
2018-10-08 20:24:56 +03:00
## TODO
2019-08-20 01:05:32 +03:00
See [todo list][todo]
2018-10-24 02:52:33 +03:00
## Issues
2018-12-06 00:07:39 +03:00
- Atomic:
2019-05-29 02:45:31 +03:00
- We need atomic type around `f32` but there is no this type in the stardard Rust
- Using [atomic-rs](https://github.com/Amanieu/atomic-rs) to do this.
2019-08-15 02:24:18 +03:00
- `kAudioDevicePropertyBufferFrameSize` cannot be set when another stream using the same device with smaller buffer size is active. See [here][chg-buf-sz] for details.
2019-04-04 00:49:46 +03:00
### Test issues
2019-08-15 02:24:18 +03:00
- Fail to run tests that depend on `AggregateDevice::create_blank_device` with the tests that work with the device event listeners
- The `AggregateDevice::create_blank_device` will add an aggregate device to the system and fire the device-change events indirectly.
- `TestDeviceSwitcher` cannot work when there is an alive full-duplex stream
- An aggregate device will be created for a duplex stream when its input and output devices are different.
- `TestDeviceSwitcher` will cached the available devices, upon it's created, as the candidates for default device
- Hence the created aggregate device may be cached in `TestDeviceSwitcher`
- If the aggregate device is destroyed (when the destroying the duplex stream created it) but the `TestDeviceSwitcher` is still working,
it will set a destroyed device as the default device
- See details in [device_change.rs](src/backend/tests/device_change.rs)
2018-10-08 20:24:56 +03:00
2019-08-20 01:05:32 +03:00
## Branches
2019-08-20 01:05:32 +03:00
- [trailblazer][trailblazer]: Main branch
- [plain-translation-from-c][from-c]: The code is rewritten from C code on a line-by-line basis
- [ocs-disposal][ocs-disposal]: The first version that replace our custom mutex by Rust Mutex
[cubeb]: https://github.com/mozilla/cubeb "Cross platform audio library"
[cubeb-au]: https://github.com/mozilla/cubeb/blob/master/src/cubeb_audiounit.cpp "Cubeb AudioUnit"
2018-11-02 21:16:32 +03:00
2019-02-26 22:12:06 +03:00
[chg-buf-sz]: https://cs.chromium.org/chromium/src/media/audio/mac/audio_manager_mac.cc?l=982-989&rcl=0207eefb445f9855c2ed46280cb835b6f08bdb30 "issue on changing buffer size"
2019-08-15 02:24:18 +03:00
[todo]: todo.md
[bmo1572273]: https://bugzilla.mozilla.org/show_bug.cgi?id=1572273
2019-08-20 01:05:32 +03:00
[bmo1572273-c13]: https://bugzilla.mozilla.org/show_bug.cgi?id=1572273#c13
[from-c]: https://github.com/mozilla/cubeb-coreaudio-rs/tree/plain-translation-from-c
[ocs-disposal]: https://github.com/mozilla/cubeb-coreaudio-rs/tree/ocs-disposal
[trailblazer]: https://github.com/mozilla/cubeb-coreaudio-rs/tree/trailblazer