Repository navigation
audiograph: Graph.swap, and carry() from a graph the pump is parked on - #350
Merged
Merged
Conversation
swap(other) trades two graphs' patches under the pump lock, so a patch built and carried beside a playing graph takes its place on a block boundary while whatever pulls the graph keeps pulling the same object. carry() now works on a pumped graph while the pump is parked. carry() also holds each borrowed table once, where it used to append the source's whole list per node carried, which multiplied with each patch change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A patch change on a graph the audio pump is playing can now land on a block boundary without the pump, an output or a mixer having to be handed a new object.
Graph.swap(other)trades the two graphs' patches (nodes, buffers, wiring, queue, borrowed tables) under the pump lock. The graph that is pulled keeps its identity, its output blocks and its frame count, and rendersother's patch from the next block. It refuses a non-graph withTypeErrorand a graph of another sample rate, block size or channel count withValueError. MicroPython, CPython and the CircuitPython binding all have it.carry()used to refuse a graph the pump was pulling. It now works while the pump is parked (audiopump.park()), so the sequence is: build the new graph while the pump plays, park, carry, swap, unpark. On CPython's service-mode pump nothing renders between two calls, so it needs no park there.It also fixes a leak in
carry(): each carried node appended the source's whole list of borrowed wow tables, so a patch carrying many nodes multiplied that list with every change (2.3 MB after six changes of an eight-delay patch; an instrument with 99 nodes ran out of memory on the third). Each table is now held once. The new test fails on the old code with exactly that growth.Docs: "Swapping while the pump plays" in
docs/how-it-works/audiograph.md.Checked:
tests/test_cpython_audiograph.py(24 pass, the four new ones among them). Built into the MicroPython unix port and used by a rack that recompiles while the pump plays, where the stream stays byte-equal to a rack built with the change from the swap block on.