feat(desktop): add opt-in Darwin audio output
This commit is contained in:
parent
902c892d3f
commit
2ea7164d9a
21 changed files with 1311 additions and 30 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Audio device subset
|
||||
|
||||
The core models Direct Sound A/B, bounded sound DMA, and programmable sound generator (PSG) channels 1–4.
|
||||
Wave channel 3 supports single-bank playback only. The core does not produce desktop audio.
|
||||
Wave channel 3 supports single-bank playback only. Optional fixed-rate capture supplies samples to the separate Darwin output adapter.
|
||||
`Memory::audio_level()` exposes the current digital stereo level for deterministic inspection, not a continuous sample stream.
|
||||
|
||||
## Registers and PSG state
|
||||
|
|
@ -262,6 +262,43 @@ Capture is disabled by default. Changing enable state clears queued frames, phas
|
|||
Repeating the current enable state preserves capture state. Configure capture between machine steps.
|
||||
Original tests cover exact sample boundaries, timer consumption, pulse phases, batching, queue overflow, HALT/STOP, and transactional rollback.
|
||||
|
||||
## Darwin output adapter
|
||||
|
||||
Use `--audio` with `--rom ... --window` to enable CPAL 0.16/CoreAudio output on macOS.
|
||||
Windows remain muted by default. Terminal runs, ROM suites, and demos do not open an audio device.
|
||||
The flag is invalid in terminal mode and cannot be repeated. Other platforms currently report an explicit unsupported-platform error.
|
||||
|
||||
The adapter opens the default output device at its default configuration.
|
||||
Supported formats are float32, signed16, and unsigned16, with 8–192 kHz rates and 1–32 channels.
|
||||
Stereo maps to the first two channels. Mono averages left/right; additional channels receive silence.
|
||||
Device initialization, unsupported formats, and stream errors fail the audio-enabled run rather than silently switching to muted execution.
|
||||
Omit `--audio` to run without an audio device.
|
||||
|
||||
The core's 32,768 Hz frames enter a bounded 8,192-frame host queue.
|
||||
Playback waits for 1,024 frames before starting or resuming after an underrun.
|
||||
Linear interpolation converts to the device rate. A 20 Hz high-pass filter removes DC, followed by conservative 25% host gain and clipping.
|
||||
These are presentation choices, not a measured GBA analog model or band-limited reconstruction.
|
||||
High-frequency aliases, startup transients, and channel-model inaccuracies remain possible.
|
||||
|
||||
The data callback performs no allocation, blocking lock, emulation step, or log write.
|
||||
It tries the queue lock once; contention produces silence and increments a counter.
|
||||
An underrun produces silence and returns to the prefill state. Overflow discards new input frames and records the loss.
|
||||
The final report includes submitted/nonzero-input frames, callbacks, nonzero-output frames, underruns, dropped input, and lock misses.
|
||||
Zero submitted frames can indicate an unfocused window, not a failed output device.
|
||||
The window treats a core capture overflow as an error; it drains samples between bounded CPU slices.
|
||||
The callback cannot advance emulator clocks or request extra emulation work.
|
||||
|
||||
Focus loss and STOP clear queued host audio and conversion state. Muted frames are drained without being submitted.
|
||||
The device may still finish its already-submitted buffer. Resume waits for fresh prefill instead of replaying stale samples.
|
||||
Audio-enabled windows use absolute frame deadlines with at most one frame of catch-up.
|
||||
This reduces sleep drift without skipping emulated frames or accumulating unbounded catch-up work.
|
||||
Slow hosts can still underrun. Sample delivery is not a claim of uninterrupted or hardware-faithful sound.
|
||||
|
||||
Native checks on Darwin arm64 exercised a quiet original tone and an original wave-ROM window through CoreAudio.
|
||||
A 900-frame local Emerald run reached its limit with 554,484 nonzero device-output frames, zero dropped input frames, and 13 underruns.
|
||||
Those counters demonstrate output submission, not human listening, correct music, or game compatibility.
|
||||
Audio quality and physical speaker/headphone output still require a manual listening check.
|
||||
|
||||
## Validation and remaining work
|
||||
|
||||
Original tests cover signed samples, byte order, queue capacity, partial writes, resets, underflow, stereo routing, and clipping.
|
||||
|
|
@ -278,13 +315,16 @@ CPU/DMA tests include noise register writes at bus completion and failed-step ro
|
|||
BIOS reset tests verify that selected sound reset stops all supported PSG channels, while unselected sound state remains active.
|
||||
|
||||
These tests validate the documented nominal model, not hardware audio fidelity.
|
||||
Remaining audio work: two-bank wave playback, verified live bank changes, hardware PWM sampling, filtering/resampling, and a Darwin host backend.
|
||||
Remaining audio work: two-bank wave playback, verified live bank changes, hardware PWM sampling, improved reconstruction, and lower-underrun pacing.
|
||||
A local Emerald input probe exposed a wave trigger with the gate disabled. This is now accepted without activating playback.
|
||||
The same scheduled-input probe passes that point and completes its extended frame budget; audible output and gameplay remain unverified.
|
||||
The same scheduled-input probe passes that point and completes its extended frame budget; gameplay remains unverified.
|
||||
Later native output checks exercise the host audio path separately; they do not establish game-audio accuracy.
|
||||
See [the local runtime result](../research/emerald-reset.md).
|
||||
|
||||
## References
|
||||
|
||||
- [CPAL 0.16.0](https://docs.rs/cpal/0.16.0/cpal/): default device/configuration, typed output callbacks, sample formats, CoreAudio backend, and stream lifecycle. CPAL is a macOS-only desktop dependency here.
|
||||
|
||||
- [GBATEK wave channel 3](https://problemkaputt.de/gbatek-gba-sound-channel-3-wave-output.htm): bank selection, nibble order, rotating RAM, sample rate, length, and force volume.
|
||||
- [NanoBoyAdvance wave at 55b5cf0a](https://github.com/nba-emu/NanoBoyAdvance/blob/55b5cf0ae3d929582ac5bfd486558173502b8354/src/nba/src/hw/apu/channel/wave_channel.cc) and [header](https://github.com/nba-emu/NanoBoyAdvance/blob/55b5cf0ae3d929582ac5bfd486558173502b8354/src/nba/src/hw/apu/channel/wave_channel.hh): signed gain and rate comparison; pointer-based RAM and two-bank/retrigger differences are not copied.
|
||||
|
||||
|
|
|
|||
|
|
@ -544,6 +544,7 @@ Unsupported SWIs, unsupported exception vectors, and null/misaligned IRQ callbac
|
|||
The CPU reports `CpuError::UnsupportedInstruction` with `bios::UNSUPPORTED_TRAP`, rather than silently treating a service as a no-op.
|
||||
Invalid arithmetic/decompression arguments use the same CPU error type with the distinct `bios::INVALID_ARGUMENT_TRAP` instruction.
|
||||
Prior boot/service steps remain committed on failure.
|
||||
Two-bank wave playback, host audio output, connected serial links, HardReset, and serial/Game Pak STOP wake-up remain unimplemented.
|
||||
Two-bank wave playback, connected serial links, HardReset, and serial/Game Pak STOP wake-up remain unimplemented.
|
||||
Darwin ROM windows can enable host audio with `--audio`; this does not extend BIOS coverage.
|
||||
Disconnected normal serial transfers use the [bounded serial model](serial.md); cancel active transfers before BIOS serial reset.
|
||||
This subset is not sufficient for Pokémon Emerald compatibility.
|
||||
|
|
|
|||
|
|
@ -135,5 +135,9 @@ The CPU writes the palette: blue at rest, red while Z is held, and green while R
|
|||
Right takes priority over Z. Other buttons have no visible effect in this small program.
|
||||
No game or firmware content is included.
|
||||
|
||||
Both ROM modes lack audio, saves, and per-step tracing. Commercial-game compatibility remains unverified and unsupported.
|
||||
ROM windows can enable Darwin output with `--audio`; they are muted by default.
|
||||
The option requires a usable default audio device. Device/configuration errors fail explicitly; omit the flag to run muted.
|
||||
Focus loss and STOP clear queued audio. See [audio output and its limits](audio.md#darwin-output-adapter).
|
||||
Terminal mode has no audio. Both modes lack save writing/persistence and per-step tracing.
|
||||
Commercial-game compatibility remains unverified and unsupported.
|
||||
Only load files that you may lawfully use. Do not commit game ROMs or firmware.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue