1# TO DO
2
3## General
4
5- Resolve the [issues](https://github.com/ChunMinChang/cubeb-coreaudio-rs/issues)
6- Some of bugs are found when adding tests. Search *FIXIT* to find them.
7- Remove `#[allow(non_camel_case_types)]`, `#![allow(unused_assignments)]`, `#![allow(unused_must_use)]`
8- Use `ErrorChain`
9- Centralize the error log in one place
10- Support `enumerate_devices` with in-out type?
11- Monitor `kAudioDevicePropertyDeviceIsAlive` for output device.
12- Create a wrapper for `CFArrayCreateMutable` like what we do for `CFMutableDictionaryRef`
13- Create a wrapper for property listener’s callback
14- Use `Option<AggregateDevice>` rather than `AggregateDevice` for `aggregate_device` in `CoreStreamData`
15
16### Type of stream
17
18- Use `Option<device_info>` rather than `device_info` for `{input, output}_device` in `CoreStreamData`
19- Use `Option<StreamParams>` rather than `StreamParams` for `{input, output}_stream_params` in `CoreStreamData`
20- Same as `{input, output}_desc`, `{input, output}_hw_rate`, ...etc
21- It would much clearer if we have a `struct X` to wrap all the above stuff and use `input_x` and `output_x` in `CoreStreamData`
22
23## Separate the stream implementation from the interface
24
25The goal is to separate the audio stream into two parts(modules).
26One is _inner_, the other is _outer_.
27
28- The _outer_ stream implements the cubeb interface, based on the _inner_ stream.
29- The _inner_ stream implements the stream operations based on the _CoreAudio_ APIs.
30Now the _outer_ stream is named `AudioUnitStream`, the _inner_ stream is named `CoreStreamData`.
31
32The problem now is that we don't have a clear boundry of the data ownership
33between the _outer_ stream and _inner_ stream. They access the data owned by the other.
34
35- `audiounit_property_listener_callback` is tied to _outer_ stream
36but the event listeners are in _inner_ stream
37- `audiounit_input_callback`, `audiounit_output_callback` are registered by the _inner_ stream
38but the main logic are tied to _outer_ stream
39
40### Callback separation
41
42- Create static callbacks in _inner_ stream
43- Render _inner_ stream's callbacks to _outer_ stream's callbacks
44
45### Reinitialization
46
47If the _outer_ stream and the _inner_ stream are separate properly,
48when we need to reinitialize the stream, we can just drop the _inner_ stream
49and create a new one. It's easier than the current implementation.
50
51## Aggregate device
52
53### Usage policy
54
55- [BMO 1563475][bmo1563475]: Only use _aggregate device_ when the mic is a input-only and the speaker is output-only device.
56- Test if we should do drift compensation.
57- Add a test for `should_use_aggregate_device`
58  - Create a dummy stream and check
59  - Check again after reinit
60    - Input only: expect false
61    - Output only: expect false
62    - Duplex
63    - Default input and output are different and they are mic-only and speaker-only: expect true
64    - Otherwise: expect false
65
66[bmo1563475]: https://bugzilla.mozilla.org/show_bug.cgi?id=1563475#c4
67
68### Get sub devices
69
70- A better pattern for `AggregateDevice::get_sub_devices`
71
72### Set sub devices
73
74- We will add overlapping devices between `input_sub_devices` and `output_sub_devices`.
75  - if they are same device
76  - if either one of them or both of them are aggregate devices
77
78### Setting master device
79
80- We always set the master device to the first subdevice of the default output device
81  but the output device (forming the aggregate device) may not be the default output device
82- Check if the first subdevice of the default output device is in the list of
83  sub devices list of the aggregate device
84- Check the `name: CFStringRef` of the master device is not `NULL`
85
86### Mixer
87
88- Don't force output device to mono or stereo when the output device has one or two channel
89  - unless the output devicv is _Bose QC35, mark 1 and 2_.
90
91## Interface to system types and APIs
92
93- Check if we need `AudioDeviceID` and `AudioObjectID` at the same time
94- Create wrapper for `AudioObjectGetPropertyData(Size)` with _qualifier_ info
95- Create wrapper for `CF` related types
96- Create wrapper struct for `AudioObjectId`
97  - Add `get_data`, `get_data_size`, `set_data`
98- Create wrapper struct for `AudioUnit`
99  - Implement `get_data`, `set_data`
100- Create wrapper for `audio_unit_{add, remove}_property_listener`, `audio_object_{add, remove}_property_listener` and their callbacks
101  - Add/Remove listener with generic `*mut T` data, fire their callback with generic `*mut T` data
102
103## [Cubeb Interface][cubeb-rs]
104
105- Implement `From` trait for `enum cubeb_device_type` so we can use `devtype.into()` to get `ffi::CUBEB_DEVICE_TYPE_*`.
106- Implement `to_owned` in [`StreamParamsRef`][cubeb-rs-stmparamsref]
107- Check the passed parameters like what [cubeb.c does][cubeb-stm-check]!
108  - Check the input `StreamParams` parameters properly, or we will set a invalid format into `AudioUnit`.
109  - For example, for a duplex stream, the format of the input stream and output stream should be same.
110      Using different stream formats will cause memory corruption
111      since our resampler assumes the types (_short_ or _float_) of input stream (buffer) and output stream (buffer) are same
112      (The resampler will use the format of the input stream if it exists, otherwise it uses the format of the output stream).
113  - In fact, we should check **all** the parameters properly so we can make sure we don't mess up the streams/devices settings!
114
115[cubeb-rs]: https://github.com/djg/cubeb-rs "cubeb-rs"
116[cubeb-rs-stmparamsref]: https://github.com/djg/cubeb-rs/blob/78ed9459b8ac2ca50ea37bb72f8a06847eb8d379/cubeb-core/src/stream.rs#L61 "StreamParamsRef"
117[cubeb-stm-check]: https://github.com/kinetiknz/cubeb/blob/a971bf1a045b0e5dcaffd2a15c3255677f43cd2d/src/cubeb.c#L70-L108
118
119## Test
120
121- Rewrite some tests under _cubeb/test/*_ in _Rust_ as part of the integration tests
122  - Add tests for capturing/recording, output, duplex streams
123- Update the manual tests
124  - Those tests are created in the middle of the development. Thay might be not outdated now.
125