Merge lang/i18n-data-fill 5d9f9cf2: ludic.audio has one aud_play holding the only Audio.play_at
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
740ac2a879
3 changed files with 16 additions and 13 deletions
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
A game's sounds, and the one door to the runtime's `Audio.*`. Uses nothing.
|
A game's sounds, and the one door to the runtime's `Audio.*`. Uses nothing.
|
||||||
|
|
||||||
**`Audio.play` is the interface; the world goes through `aud_emit`.** A click, a chime, a shutter
|
**`aud_ui` is the interface; the world goes through `aud_emit`.** A click, a chime, a shutter
|
||||||
and a warning happen in the player's head and are played flat (`aud_ui`). Everything that happens in
|
and a warning happen in the player's head and are played flat (`aud_ui`, on the interface channel). Everything that happens in
|
||||||
the world - a foot, an axe, a pot, a splash, a call - carries a gain, a pitch and a pan from where it
|
the world - a foot, an axe, a pot, a splash, a call - carries a gain, a pitch and a pan from where it
|
||||||
is relative to the listener, even when that is the listener's own position. A game that played half
|
is relative to the listener, even when that is the listener's own position. A game that played half
|
||||||
its world flat had an axe across the camp as loud as your own and a pot at the fire as loud from the
|
its world flat had an axe across the camp as loud as your own and a pot at the fire as loud from the
|
||||||
|
|
@ -36,10 +36,10 @@ port AudioFiles { cache_dir: fn() -> string } # "" (the default): a p
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `aud_emit(h, gain, pitch, pan)` | a world sound, as given: the ONE call to `Audio.play_at`, and the one place a float becomes the runtime's Q16.16 |
|
| `aud_emit(h, gain, pitch, pan)` | a world sound, as given, handed to `aud_play`: the one place a float becomes the runtime's Q16.16 |
|
||||||
| `aud_emit_at(h, x, z, range) -> bool` | a world sound at a place, gain, pitch and pan from the listener; false when out of earshot |
|
| `aud_emit_at(h, x, z, range) -> bool` | a world sound at a place, gain, pitch and pan from the listener; false when out of earshot |
|
||||||
| `aud_gain_at(x, z, range)`, `aud_pan_at(x, z)`, `aud_pitch_at(gain)` | a shaped roll-off (not an inverse square: that is deafening or inaudible in a valley of trees), the side from the listener's heading (ahead and behind centred), and a semitone lower at the edge of hearing |
|
| `aud_gain_at(x, z, range)`, `aud_pan_at(x, z)`, `aud_pitch_at(gain)` | a shaped roll-off (not an inverse square: that is deafening or inaudible in a valley of trees), the side from the listener's heading (ahead and behind centred), and a semitone lower at the edge of hearing |
|
||||||
| `aud_ui(h)` | an interface sound, flat: the ONE call to `Audio.play` |
|
| `aud_ui(h)` | an interface sound, flat, at the interface channel's volume |
|
||||||
| `aud_music(h)`, `aud_stop_music()`, `aud_master(v)` | the loop and the master volume |
|
| `aud_music(h)`, `aud_stop_music()`, `aud_master(v)` | the loop and the master volume |
|
||||||
| `aud_load(path) -> int`, `aud_unpack(path, name)`, `aud_tried()`, `aud_live()` | a clip, loaded past `Audio.load`'s blind spot; how many were asked for and how many loaded |
|
| `aud_load(path) -> int`, `aud_unpack(path, name)`, `aud_tried()`, `aud_live()` | a clip, loaded past `Audio.load`'s blind spot; how many were asked for and how many loaded |
|
||||||
| `aud_wav_seconds(path, fallback)` | a PCM WAV's length from its header, for re-triggering a loop before it ends |
|
| `aud_wav_seconds(path, fallback)` | a PCM WAV's length from its header, for re-triggering a loop before it ends |
|
||||||
|
|
@ -58,8 +58,8 @@ indistinguishable from a working one.
|
||||||
## The guard
|
## The guard
|
||||||
|
|
||||||
A game keeps the rule with a grep (Maroon Lake's `tests/audio.sh`): nothing outside this package
|
A game keeps the rule with a grep (Maroon Lake's `tests/audio.sh`): nothing outside this package
|
||||||
names `Audio.*`, `Audio.play` appears once here (in `aud_ui`) and `Audio.play_at` once (in
|
names `Audio.*`, `Audio.play_at` appears once here (in `aud_play`, which `aud_emit` and `aud_ui` both
|
||||||
`aud_emit`), and the game calls `aud_ui` only for its interface sounds.
|
call) and `Audio.play` not at all, and the game calls `aud_ui` only for its interface sounds.
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# emit.ludic - the only calls into the runtime's playback. aud_emit is the ONE place a float
|
# emit.ludic - the only calls into the runtime's playback: aud_play, under aud_emit and aud_ui, is the ONE
|
||||||
# crosses into Audio.play_at's Q16.16: handed over unconverted, 0.94 as a pitch clamped to 4x and
|
# place a float crosses into Audio.play_at's Q16.16 - handed over unconverted, 0.94 as a pitch clamped to 4x
|
||||||
# -0.85 as a pan to hard left, and every sound in a valley played fast out of one speaker
|
# and -0.85 as a pan to hard left, and every sound in a valley played fast out of one speaker
|
||||||
export state AudioState {
|
export state AudioState {
|
||||||
last_gain: float = 0.0
|
last_gain: float = 0.0
|
||||||
last_pitch: float = 0.0
|
last_pitch: float = 0.0
|
||||||
|
|
@ -17,9 +17,12 @@ export function aud_emit(audio_st: mut AudioState, h: int, gain: float, pitch: f
|
||||||
audio_st.last_pitch = pitch
|
audio_st.last_pitch = pitch
|
||||||
audio_st.last_pan = pan
|
audio_st.last_pan = pan
|
||||||
audio_st.emitted += 1
|
audio_st.emitted += 1
|
||||||
Audio.play_at(h, fixed(gain), fixed(pitch), fixed(pan))
|
aud_play(h, gain, pitch, pan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# the ONE call into the runtime's playback, and the one place a float becomes its Q16.16
|
||||||
|
function aud_play(h: int, gain: float, pitch: float, pan: float) -> void { Audio.play_at(h, fixed(gain), fixed(pitch), fixed(pan)) }
|
||||||
|
|
||||||
# a sound at a place in the world, heard within `range` metres: false (and nothing played) when the
|
# a sound at a place in the world, heard within `range` metres: false (and nothing played) when the
|
||||||
# listener is out of earshot
|
# listener is out of earshot
|
||||||
export function aud_emit_at(audio_st: mut AudioState, h: int, x: float, z: float, range: float) -> bool {
|
export function aud_emit_at(audio_st: mut AudioState, h: int, x: float, z: float, range: float) -> bool {
|
||||||
|
|
@ -33,7 +36,7 @@ export function aud_emit_at(audio_st: mut AudioState, h: int, x: float, z: float
|
||||||
export function aud_ui(audio_st: mut AudioState, h: int) -> void {
|
export function aud_ui(audio_st: mut AudioState, h: int) -> void {
|
||||||
if h == 0 { return }
|
if h == 0 { return }
|
||||||
audio_st.emitted += 1
|
audio_st.emitted += 1
|
||||||
Audio.play_at(h, fixed(aud_channel(audio_st, AUD_CH_UI)), fixed(1.0), fixed(0.0))
|
aud_play(h, aud_channel(audio_st, AUD_CH_UI), 1.0, 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function aud_music(h: int) -> void { if h != 0 { Audio.play_music(h) } }
|
export function aud_music(h: int) -> void { if h != 0 { Audio.play_music(h) } }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# ludic.audio - Audio.play is the INTERFACE; everything that happens in the world goes through
|
# ludic.audio - aud_ui is the INTERFACE (flat, on its channel); everything that happens in the world goes
|
||||||
# aud_emit with a gain and a pan from where it is. Nothing outside this module names Audio.*.
|
# through aud_emit with a gain and a pan from where it is. Nothing outside this module names Audio.*.
|
||||||
module ludic_audio uses
|
module ludic_audio uses
|
||||||
numbers float
|
numbers float
|
||||||
import "ports.ludic"
|
import "ports.ludic"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue