Skip to content

Commit ddc9546

Browse files
committed
Split core package; align root API; tighten Fixed buffer semantics
1 parent bb31172 commit ddc9546

111 files changed

Lines changed: 2413 additions & 2292 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.beads/issues.jsonl

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

README.mbt.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ Pinned upstream reference: see `UPSTREAM.md`.
66

77
## Status
88

9-
- `Milky2018/moon_cpal`: core CPAL-like types (configs, heuristics, timestamps, sample helpers).
10-
- `Milky2018/moon_cpal/spec`: CPAL-like host/device/stream API backed by `platform` dynamic dispatch.
11-
- `Milky2018/moon_cpal/traits`: CPAL-like `HostTrait`/`DeviceTrait`/`StreamTrait` implemented for `spec`.
9+
- `Milky2018/moon_cpal`: public CPAL-like API (native-only): host/device/stream + core type re-exports.
10+
- `Milky2018/moon_cpal/core`: pure core types/errors (configs, heuristics, timestamps, sample helpers).
11+
- `Milky2018/moon_cpal/platform`: dynamic dispatch host/device/stream (backend selection).
12+
- `Milky2018/moon_cpal/spec`: root API implementation backed by `platform`.
13+
- `Milky2018/moon_cpal/traits`: CPAL-like `HostTrait`/`DeviceTrait`/`StreamTrait` implemented for the root types.
1214
- Native backends (real I/O, callback-thread model):
1315
- macOS: CoreAudio (AudioQueue)
1416
- Linux: ALSA + JACK

UPSTREAM_PARITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ MoonBit port.
2525

2626
Top-level:
2727

28-
- `lib.rs`**PARTIAL** (core types + some heuristics/tests exist; high-level host API lives in `spec`)
28+
- `lib.rs`**PARTIAL** (root API now re-exports platform + core via `core/` split; remaining: iterator-style APIs + docs)
2929
- `traits.rs`**PARTIAL** (MoonBit `traits` package exists; iterator-associated types pending)
3030
- `error.rs`**DONE** (Display-equivalent `to_string` parity + tests)
3131
- `device_description.rs`**DONE** (`direction_from_counts` parity + tests)

alsa/alsa_config_test.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///|
22
test "alsa default config matches supported configs (best-effort)" {
3-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
3+
if @core.native_os() != @core.NativeOs::Linux {
44
inspect(true, content="true")
55
return
66
}
@@ -44,7 +44,7 @@ test "alsa default config matches supported configs (best-effort)" {
4444

4545
///|
4646
test "alsa supported configs include sane buffer size ranges (best-effort)" {
47-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
47+
if @core.native_os() != @core.NativeOs::Linux {
4848
inspect(true, content="true")
4949
return
5050
}

alsa/alsa_enumerate_test.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///|
22
test "alsa: devices includes default (linux-only)" {
3-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
3+
if @core.native_os() != @core.NativeOs::Linux {
44
return
55
}
66
let h = default_host()
@@ -18,7 +18,7 @@ test "alsa: devices includes default (linux-only)" {
1818

1919
///|
2020
test "alsa: default devices are always Some (linux-only)" {
21-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
21+
if @core.native_os() != @core.NativeOs::Linux {
2222
inspect(true, content="true")
2323
return
2424
}

alsa/buffer_fixed_semantics_wbtest.mbt

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///|
2-
test "alsa fixed buffer 0 is invalid argument (best-effort)" {
3-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
2+
test "alsa fixed buffer 0 is stream_config_not_supported (best-effort)" {
3+
if @core.native_os() != @core.NativeOs::Linux {
44
inspect(true, content="true")
55
return
66
}
@@ -16,10 +16,10 @@ test "alsa fixed buffer 0 is invalid argument (best-effort)" {
1616
} noraise {
1717
x => x
1818
}
19-
let sc = @moon_cpal.StreamConfig::new(
19+
let sc = @core.StreamConfig::new(
2020
cfg.channels(),
2121
cfg.sample_rate(),
22-
@moon_cpal.BufferSize::fixed(0),
22+
@core.BufferSize::fixed(0),
2323
)
2424
try
2525
dev.build_output_stream_raw(
@@ -32,7 +32,7 @@ test "alsa fixed buffer 0 is invalid argument (best-effort)" {
3232
catch {
3333
e =>
3434
match e {
35-
@moon_cpal.BuildStreamError::InvalidArgument =>
35+
@core.BuildStreamError::StreamConfigNotSupported =>
3636
inspect(true, content="true")
3737
_ => inspect(false, content="true")
3838
}
@@ -48,7 +48,7 @@ test "alsa fixed buffer 0 is invalid argument (best-effort)" {
4848

4949
///|
5050
test "alsa fixed buffer larger than supported range fails (best-effort)" {
51-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
51+
if @core.native_os() != @core.NativeOs::Linux {
5252
inspect(true, content="true")
5353
return
5454
}
@@ -64,11 +64,23 @@ test "alsa fixed buffer larger than supported range fails (best-effort)" {
6464
} noraise {
6565
x => x
6666
}
67-
let big = 1000000000
68-
let sc = @moon_cpal.StreamConfig::new(
67+
let max_buf = match cfg.buffer_size() {
68+
@core.SupportedBufferSize::Unknown => {
69+
inspect(true, content="true")
70+
return
71+
}
72+
@core.SupportedBufferSize::Range(max=mx, ..) => mx
73+
}
74+
// Avoid overflow when buffer size is effectively unbounded.
75+
if max_buf >= 2147483647 {
76+
inspect(true, content="true")
77+
return
78+
}
79+
let want = max_buf + 1
80+
let sc = @core.StreamConfig::new(
6981
cfg.channels(),
7082
cfg.sample_rate(),
71-
@moon_cpal.BufferSize::fixed(big),
83+
@core.BufferSize::fixed(want),
7284
)
7385
let got = try
7486
dev.build_output_stream_raw(
@@ -79,7 +91,11 @@ test "alsa fixed buffer larger than supported range fails (best-effort)" {
7991
None,
8092
)
8193
catch {
82-
_ => None
94+
e =>
95+
match e {
96+
@core.BuildStreamError::StreamConfigNotSupported => None
97+
_ => None
98+
}
8399
} noraise {
84100
s => Some(s)
85101
}

alsa/callback_timing_wbtest.mbt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
///|
22
test "alsa callback timestamps + format tags" {
3-
let want_cb = @moon_cpal.StreamInstant::new(1, 2)
4-
let want_pb = @moon_cpal.StreamInstant::new(3, 4)
3+
let want_cb = @core.StreamInstant::new(1, 2)
4+
let want_pb = @core.StreamInstant::new(3, 4)
55
let got = FixedArray::make(3, false)
66
call_output_data_callback(
77
fn(d, info) {
8-
got[0] = d.sample_format() == @moon_cpal.SampleFormat::F32
8+
got[0] = d.sample_format() == @core.SampleFormat::F32
99
got[1] = info.timestamp().callback() == want_cb
1010
got[2] = info.timestamp().playback() == want_pb
1111
},
@@ -19,12 +19,12 @@ test "alsa callback timestamps + format tags" {
1919
inspect(got[0], content="true")
2020
inspect(got[1], content="true")
2121
inspect(got[2], content="true")
22-
let want_cb2 = @moon_cpal.StreamInstant::new(5, 6)
23-
let want_cap = @moon_cpal.StreamInstant::new(7, 8)
22+
let want_cb2 = @core.StreamInstant::new(5, 6)
23+
let want_cap = @core.StreamInstant::new(7, 8)
2424
let got2 = FixedArray::make(3, false)
2525
call_input_data_callback(
2626
fn(d, info) {
27-
got2[0] = d.sample_format() == @moon_cpal.SampleFormat::I16
27+
got2[0] = d.sample_format() == @core.SampleFormat::I16
2828
got2[1] = info.timestamp().callback() == want_cb2
2929
got2[2] = info.timestamp().capture() == want_cap
3030
},

alsa/error_mapping_wbtest.mbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///|
22
test "alsa errno mapping (unit)" {
3-
if @moon_cpal.native_os() != @moon_cpal.NativeOs::Linux {
3+
if @core.native_os() != @core.NativeOs::Linux {
44
inspect(true, content="true")
55
return
66
}

alsa/ffi_native.mbt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,28 @@ pub fn device_name_utf8(id : String) -> String? {
5858
if id.length() == 0 {
5959
return None
6060
}
61-
let b1 = @moon_cpal.string_to_utf8_bytes(id)
61+
let b1 = @core.string_to_utf8_bytes(id)
6262
let id_len = b1.length()
6363
let n = alsa_device_name_utf8_len(b1, id_len)
6464
if n <= 0 {
6565
return None
6666
}
6767
let out = Bytes::make(n, (0 : Int).to_byte())
68-
let b2 = @moon_cpal.string_to_utf8_bytes(id)
68+
let b2 = @core.string_to_utf8_bytes(id)
6969
let used = alsa_device_name_utf8(b2, id_len, out, out.length())
7070
if used <= 0 {
7171
return None
7272
}
7373
let need = if used > out.length() { out.length() } else { used }
74-
Some(@moon_cpal.utf8_bytes_to_string(out, need))
74+
Some(@core.utf8_bytes_to_string(out, need))
7575
}
7676

7777
///|
7878
pub fn supported_configs_bin(id : String, is_input : Bool) -> Bytes {
7979
if id.length() == 0 {
8080
return Bytes::make(0, (0 : Int).to_byte())
8181
}
82-
let b = @moon_cpal.string_to_ascii_bytes(id)
82+
let b = @core.string_to_ascii_bytes(id)
8383
alsa_supported_configs_bin(
8484
b,
8585
b.length(),

0 commit comments

Comments
 (0)