ChiptunePlayer
Extends AudioStreamPlayer. Read from the plugin's source on every build.
An AudioStreamPlayer that plays a sound rather than a file.
The node for a .sfx.tres. Music has its own, ChiptuneMusicPlayer, which
is the same idea with a loop on it, because a song has a place the music
ends that is not the place the audio ends and a sound does not.
The same thing a ChiptuneAudioStream does, with the assembly taken out.
The resource works on any node with a stream — ours, Godot’s, another
addon’s — which is what lets it mix with a project’s existing audio, but it
is also nested two levels down a dropdown nobody has a reason to open. This
node is the discoverable half: Add Child Node, type “chiptune”, set the
document, done.
stream is hidden and not saved. It is built from document,
so showing both would be two properties that can disagree, and storing both
would put the same fact in a scene twice.
The roadmap’s runtime player grows into this: play() and stop() are already here from AudioStreamPlayer, and streaming playback with jump_to_pattern and set_channel_muted is the work that fills it out. Its 2D and 3D siblings are the same eight lines against a different base, because Godot’s three players share no common ancestor that has a stream.
Properties
document
@export_custom(PROPERTY_HINT_RESOURCE_TYPE, "ChiptuneSfxSpec") var document: ResourceThe .sfx.tres to play.
Hinted to ChiptuneSfxSpec alone so the picker and its Quick Load search
offer sounds and not every resource in the project. A song belongs on a
ChiptuneMusicPlayer, which has the loop. The hint is an editor filter and
not the contract: anything answering render() still plays when it is
assigned from code or written into a scene by hand, a song included. See
ChiptuneAudioStream.
Methods
rerender
func rerender() -> voidRenders document again, so a change made to it from a script is
heard on the next AudioStreamPlayer.play.
A document is an ordinary resource and nothing watches its fields, so a
script that changes a pitch or hands the node a ChiptuneSfx.mutate
of the spec it already holds changes nothing until the audio is asked for
again. This is that ask.
The audio is written into the stream the node already has rather than into a new one, so anything holding this node’s stream keeps the resource it was handed. It is a full render on the main thread: see “What it costs” in the module README before calling it every frame.
Constants
DERIVED_PROPERTIES
const DERIVED_PROPERTIES: Array[StringName] = [&"stream"]Neither shown nor stored. stream is built from document,
so showing it would be two properties that can disagree and storing it would
put the rendered audio in somebody’s scene file.
JamChip 0.1.0, by GlitterSnack. MIT licence. Built from the source on every merge, artwork and screenshots included, with JamChip.