Complete managed macOS platform bring-up
.NET port / test (macos-latest) (push) Canceled after 0s
.NET port / test (ubuntu-24.04) (push) Canceled after 0s
.NET port / test (windows-latest) (push) Canceled after 0s
.NET port / apple-client (push) Canceled after 0s
.NET port / cpp-conformance (push) Canceled after 0s

This commit is contained in:
2026-09-18 18:51:53 +02:00
parent ab460ae12b
commit 310c0f09dd
21 changed files with 421 additions and 83 deletions
+1 -1
View File
@@ -167,7 +167,7 @@ Two API functions let callers bypass miniaudio entirely for a stream:
| Function | Direction | Contract |
|----------|-----------|----------|
| `vc_stream_feed_pcm(c, stream_id, pcm, samples_per_channel, channels)` | **Send** — caller → network | Caller supplies interleaved int16 at the stream's sample rate (`channels` = 1 mono, 2 stereo). The core frames, Opus-encodes, AEAD-seals, and sends over UDP — identical wire path to hardware capture. The stream must already be started with `vc_stream_start`. Thread-safe; may be called from any thread (audio callback, ReplayKit delegate, SCStream callback). |
| `vc_set_pcm_sink(c, cb, user)` | **Receive** — network → caller | `cb` is called on the audio (playback) thread once per decoded Opus frame per remote stream, with `(user_id, stream_id, pcm, samples_per_channel, channels, sample_rate)`. PCM is delivered to the sink **and** the hardware device — dual output; the hardware mix is unaffected. Pass `cb=NULL` to disable (default). **Must not block** — copy what you need and return. |
| `vc_set_pcm_sink(c, cb, user)` | **Receive** — network → caller | `cb` is called on the audio (playback) thread once per decoded Opus frame per remote stream, with `(user_id, stream_id, pcm, samples_per_channel, channels, sample_rate)`. PCM is delivered to the sink **and** the hardware device — dual output; the hardware mix is unaffected. Pass `cb=NULL` to disable (default); once that call returns, no callback using the old `user` pointer remains in flight. **Must not block** — copy what you need and return. |
`vc_test_inject_capture` (the old TEST-ONLY mono-only predecessor) is a deprecated alias
for `vc_stream_feed_pcm(..., channels=1)` — kept for source compatibility.
+17 -10
View File
@@ -791,16 +791,17 @@ criterion from `roadmap.md`, re-proven against the new server.
6. **Add the allocation-regression test.**
**Exit criterion:** `test_jitter_depth`'s bounded-depth invariant holds; zero allocations per
mix cycle; a manual listen test on Windows and macOS with no audible glitching over 10
minutes.
mix cycle; real multi-human calls on Windows and macOS have no reproducible audio-quality
defects once each client is feature-complete.
**Checkpoint (2026-09-16):** `VoiceCat.Audio` now owns local Opus streams, reframing at every
protocol frame size, VAD/PTT/DTX, DRED → FEC → PLC receive recovery, bounded jitter, per-stream
controls, RNNoise and stereo mixing. Its normal encode/decode/NR/mix cycle allocates zero
managed bytes. Capture inputs use bounded non-waiting PCM rings. The Windows implementation
uses direct C# WASAPI capture, loopback and playback instead of the proposed miniaudio device
shim; the codec/DSP shim remains the only native component. A real device smoke passed, but
the required ten-minute Windows/macOS listen test is still a manual release gate.
shim; the codec/DSP shim remains the only native component. A real device smoke passed;
final listen validation is performed with real multi-human calls after feature completion,
not a synthetic ten-minute sine-wave gate.
---
@@ -850,7 +851,7 @@ Per §8.2. AppKit port, ScreenCaptureKit per-app audio selection, VoiceOver pari
**Exit criterion:** feature parity with `VoiceCatMac`, VoiceOver smoke-tested, notarized
build produced.
**Checkpoint (2026-09-16):** `clients/apple/dotnet/VoiceCat.Mac` is a separate .NET 10
**Checkpoint (2026-09-18):** `clients/apple/dotnet/VoiceCat.Mac` is a separate .NET 10
AppKit application that consumes `VoiceCat.Core` directly. It implements guest and account
connection, validated saved server profiles whose JSON never contains passwords,
interactive TOFU approval, protected-channel password prompts, channel browsing, roster,
@@ -862,11 +863,17 @@ Core Audio capture is resampled
and converted through `AVAudioConverter` before entering the managed audio engine. Stereo
playback uses `AVAudioSourceNode` and the shared bounded PCM ring; its render callback does
not allocate, lock or block. Voice stream lifetime follows subscription, disconnect and
channel changes. Current Apple API calls compile warning-free against Microsoft's
26.4.10259 macOS reference assembly, and a macOS CI job builds the native codec/DSP shim and
Apple solution. A real macOS device run and listen test remain required. The existing Swift
app remains the release client until selectable devices and the moderation/settings
surface, ScreenCaptureKit, VoiceOver
channel changes. The app now targets Microsoft's Xcode 27 preview bindings from workload
set 10.0.401. On Apple Silicon it selects a native Homebrew `protoc`, deduplicates the
transitive media dylib before AppKit bundling, uses the macOS 27 error-returning Core Audio
overloads, and keeps hardened runtime Release-only so local ad-hoc Debug builds can load
their runtime libraries. It enumerates and selects Core Audio input/output devices, requests
microphone permission explicitly, and renders through Core Audio's native planar Float32
layout. The arm64 app builds, signs, launches and displays on macOS 27. Live testing proved
physical-microphone transmission and clean peer playback; Lobby's expected DTX comfort noise
was distinguished from corruption by repeating the tone in the DTX-disabled Music Room. A
macOS CI job builds the native codec/DSP shim and Apple solution. The existing Swift app
remains the release client until the moderation/settings surface, ScreenCaptureKit, VoiceOver
validation, signing and notarization are complete.
---