Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ lines its run must print, and the gates run on the mini cluster.
bend2/main.ts the CLI; imported, the .bend loader for bun and node
bend2/base.bend the base library
bend2/bend.lean the core, mechanized in Lean
bend2/effs/ one file per IO effect, per backend
bend2/effs/ IO effects per backend; audio shares one C source
bend2/pack/ package.json, tsconfig.json, bun.lock
bend2/docs/ the papers' Typst sources, the film, gen_pins.ts (the
record pins on this Mac), gen_charts.ts (the landing
Expand Down
6 changes: 3 additions & 3 deletions bend2/base.bend
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,15 @@ def Window.close(window: Window) -> IO(Unit):
import "./effs/window_close.js"

def Audio.open(rate: U32) -> IO(Result<&1, &1, U32 & String, Audio>):
import "./effs/audio_open.c"
import "./effs/audio.c"
import "./effs/audio_open.js"

def Audio.write(audio: Audio, samples: List<&2, F32>) -> IO(Audio & U32):
import "./effs/audio_write.c"
import "./effs/audio.c"
import "./effs/audio_write.js"

def Audio.close(audio: Audio) -> IO(Unit):
import "./effs/audio_close.c"
import "./effs/audio.c"
import "./effs/audio_close.js"

# Equal
Expand Down
35 changes: 32 additions & 3 deletions bend2/effs/audio_write.c → bend2/effs/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@

// The ring: 4096 float32 stereo frames. The effects fill it on the
// evaluator's thread; the device's callback drains it and pads the
// rest of its buffer with silence. The same block sits in
// audio_write.c and audio_close.c under this guard, so that any one
// of the three effects compiles alone.
// rest of its buffer with silence. All audio effects share this source;
// each entry is present only when its effect is reachable.
#ifndef IO_RING
#define IO_RING 4096u

Expand Down Expand Up @@ -164,6 +163,24 @@ static void io_ring_free(IoRing* p) {
#endif
#endif

#ifdef CID_AUDIO_OPEN
Term audio_open_run(Env e, Term* f, IoWork* w) {
u32 rate = (u32)f[0];
IoRing* p = io_mem(calloc(1, sizeof *p));
u32 code = rate < 8000 || rate > 192000 ? EINVAL : io_ring_start(p, rate);
if (code != 0) {
io_ring_free(p);
return io_fail(e, code, code == EINVAL ? NULL : "Audio.open: no audio output");
}
return io_done(e, io_hand((intptr_t)p));
}

static void __attribute__((constructor)) audio_open_use(void) {
io_eff(CID_AUDIO_OPEN, audio_open_run, 0);
}
#endif

#ifdef CID_AUDIO_WRITE
// The samples (interleaved L R ...) into the ring; the frames queued
// after the write. Past the ring's room, the samples are dropped and
// the queue answered as it is.
Expand All @@ -189,3 +206,15 @@ Term audio_write_run(Env e, Term* f, IoWork* w) {
static void __attribute__((constructor)) audio_write_use(void) {
io_eff(CID_AUDIO_WRITE, audio_write_run, 0);
}
#endif

#ifdef CID_AUDIO_CLOSE
Term audio_close_run(Env e, Term* f, IoWork* w) {
io_ring_free((IoRing*)(uintptr_t)io_hand_v(f[0]));
return term_pak(CID_UNIT, 0);
}

static void __attribute__((constructor)) audio_close_use(void) {
io_eff(CID_AUDIO_CLOSE, audio_close_run, 0);
}
#endif
174 changes: 0 additions & 174 deletions bend2/effs/audio_close.c

This file was deleted.

Loading