runtime/audio (macOS): voices on one AVAudioEngine instead of an AVAudioPlayer per sound
AVFAudio keeps a 64-byte AudioQueueOwner for good on every AVAudioPlayer play after the clip has finished - measured one a play, whatever is called around it (prepareToPlay, pause, no rewind) and still there after the player is released; a stop before the play made one every time. The windowed walk showed it as AudioQueueOwner 73 -> 87 in a minute. A sound is now decoded once into a PCM buffer and played by a voice of its own on one shared engine: a player node (the buffer scheduled again on each play, looping for -1), a varispeed (the rate) and a small mixer (volume and pan). snd_playing compares the uptime clock with the end worked out when the clip was played (asking the node where it is made two AVAudioTime objects a call), and snd_play drains an autorelease pool of its own. The C interface is unchanged. A harness driving snd_* directly (400 plays past the end, the playing flag checked during and after each, a loop and a stop, the setters) holds the heap flat to a block and gets the flag right 400 of 400; the windowed valley compiles and links against it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
34421b8015
commit
a5f6c02a09
3 changed files with 295 additions and 96 deletions
|
|
@ -1,5 +1,5 @@
|
|||
# load.ludic - a clip the runtime can actually open. Audio.load takes a real FILESYSTEM path (it
|
||||
# bottoms out in AVAudioPlayer), not the pack-aware file_open every other asset arrives through: in a
|
||||
# bottoms out in AVAudioFile), not the pack-aware file_open every other asset arrives through: in a
|
||||
# bundle every clip loads as 0 while Fs.exists, which IS pack-aware, says it is there. So try the
|
||||
# runtime's path, and on 0 lift the bytes out of the pack into the cache directory and load that.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue