|
16 | 16 |
|
17 | 17 | # moon_cpal |
18 | 18 |
|
19 | | -MoonBit port of RustAudio `cpal` (native-only). |
| 19 | +CPAL-like audio I/O for MoonBit (native-only). |
20 | 20 |
|
21 | | -Pinned upstream reference: see `UPSTREAM.md`. |
| 21 | +## Install |
22 | 22 |
|
23 | | -## Status |
24 | | - |
25 | | -- `Milky2018/moon_cpal`: public CPAL-like API (native-only): host/device/stream + core type re-exports. |
26 | | -- `Milky2018/moon_cpal/core`: pure core types/errors (configs, heuristics, timestamps, sample helpers). |
27 | | -- `Milky2018/moon_cpal/platform`: dynamic dispatch host/device/stream (backend selection). |
28 | | -- `Milky2018/moon_cpal/spec`: root API implementation backed by `platform`. |
29 | | -- `Milky2018/moon_cpal/traits`: CPAL-like `HostTrait`/`DeviceTrait`/`StreamTrait` implemented for the root types. |
30 | | -- Native backends (real I/O, callback-thread model): |
31 | | - - macOS: CoreAudio (AudioQueue) |
32 | | - - Linux: ALSA + JACK |
33 | | - - Windows: WASAPI |
34 | | - |
35 | | -Note: `moon.mod.json` sets `preferred-target: native`. Non-native targets are not supported. |
36 | | - |
37 | | -## Native Link Strategy (`build.js`) |
38 | | - |
39 | | -- The project uses Moon's prebuild hook (`--moonbit-unstable-prebuild`) with `build.js` to emit per-OS `link_configs`. |
40 | | -- This mirrors the `tonyfettes/raylib` style: keep `moon.pkg` files free of hard-coded cross-platform linker flag unions and let `build.js` choose the active platform link set. |
41 | | -- Linux/macOS/Windows now receive only their own native link requirements. |
42 | | -- Downstream dependency smoke (`ci/downstream_smoke`) validates that `Milky2018/moon_cpal` compiles as a dependency across Linux/macOS/Windows with this strategy. |
43 | | - |
44 | | -## Run unit tests (native) |
| 23 | +Add dependency in `moon.mod.json`: |
45 | 24 |
|
| 25 | +```json |
| 26 | +{ |
| 27 | + "deps": { |
| 28 | + "Milky2018/moon_cpal": "0.11.1" |
| 29 | + } |
| 30 | +} |
46 | 31 | ``` |
47 | | -moon test --target native |
48 | | -``` |
49 | | - |
50 | | -## Enumerate hosts/devices (native) |
51 | 32 |
|
| 33 | +`moon_cpal` supports `native` target only. |
| 34 | + |
| 35 | +## Quick Start (Typed Output Stream) |
| 36 | + |
| 37 | +```moonbit |
| 38 | +let host = @moon_cpal.default_host() |
| 39 | +let device = match host.default_output_device() { |
| 40 | + Some(d) => d |
| 41 | + None => fail!("no output device") |
| 42 | +} |
| 43 | +let cfg = try! device.default_output_config() |
| 44 | +let stream_cfg = cfg.config() |
| 45 | +let stream = try! device.build_output_stream_f32( |
| 46 | + stream_cfg, |
| 47 | + fn(samples, _info) { |
| 48 | + for i = 0; i < samples.length(); i = i + 1 { |
| 49 | + samples[i] = 0.0 |
| 50 | + } |
| 51 | + }, |
| 52 | + fn(err) { println("stream error: \{err}") }, |
| 53 | + None, |
| 54 | +) |
| 55 | +try! stream.play() |
52 | 56 | ``` |
53 | | -moon run --target native cmd/enumerate |
54 | | -``` |
55 | | - |
56 | | -## Stream smoke tests (native) |
57 | | - |
58 | | -macOS: |
59 | 57 |
|
60 | | -``` |
61 | | -moon run --target native cmd/macos_smoke |
| 58 | +## Quick Start (Raw Output Stream) |
| 59 | + |
| 60 | +Use `build_output_stream_raw` when you need format-specific writes: |
| 61 | + |
| 62 | +```moonbit |
| 63 | +let stream = try! device.build_output_stream_raw( |
| 64 | + stream_cfg, |
| 65 | + cfg.sample_format(), |
| 66 | + fn(data, _info) { |
| 67 | + match data.sample_format() { |
| 68 | + @moon_cpal.SampleFormat::F32 => |
| 69 | + ignore(data.write_f32(Array::make(data.len(), 0.0))) |
| 70 | + @moon_cpal.SampleFormat::I16 => |
| 71 | + ignore(data.write_i16(Array::make(data.len(), 0))) |
| 72 | + @moon_cpal.SampleFormat::I24 => |
| 73 | + ignore(data.write_i24(Array::make(data.len(), @moon_cpal.I24::new(0)))) |
| 74 | + _ => data.clear() |
| 75 | + } |
| 76 | + }, |
| 77 | + fn(_err) { }, |
| 78 | + None, |
| 79 | +) |
62 | 80 | ``` |
63 | 81 |
|
64 | | -``` |
65 | | -moon run --target native cmd/macos_stream_smoke |
66 | | -``` |
| 82 | +`Data` exposes full numeric write APIs: |
| 83 | +`write_i8`, `write_u8`, `write_u16`, `write_i16`, `write_u24`, `write_i24`, |
| 84 | +`write_u32`, `write_i32`, `write_f32`, `write_u64`, `write_i64`, `write_f64`. |
67 | 85 |
|
68 | | -Linux: |
| 86 | +## Notes |
69 | 87 |
|
70 | | -``` |
71 | | -moon run --target native cmd/alsa_stream_smoke |
72 | | -moon run --target native cmd/jack_stream_smoke |
73 | | -``` |
74 | | - |
75 | | -Windows: |
76 | | - |
77 | | -``` |
78 | | -moon run --target native cmd/wasapi_stream_smoke |
79 | | -``` |
| 88 | +- Use `stream.pause()` / `stream.close()` to control lifecycle. |
| 89 | +- Use `default_input_device()` + `build_input_stream_*` for capture. |
0 commit comments