Interface AudioStreamSource
- All Superinterfaces:
AutoCloseable
AudioClip-style all-at-once (a four
minute track fully decoded is ~40 MB of heap; streamed it is a few hundred
KB of ring buffers). Obtained from AudioDecoder.openStream(java.nio.file.Path) and
consumed by AudioEngine.playStream(limn.sound.AudioStreamSource, limn.sound.PlayOptions).
Threading: after playStream takes ownership, calls come from the
thread that starts the stream (initial priming reads) and from the engine's
streaming thread (refills, seek(long), the final close()), never
concurrently, serialized by the engine. Implementations need no
synchronization but must not assume any particular thread.
-
Method Summary
Modifier and TypeMethodDescriptiondefault booleancanSeek()intchannels()voidclose()Releases decoder/file resources.intreadFrames(short[] out, int maxFrames) Decodes up tomaxFramesframes intoout(interleaved,frames × channelsshorts from index 0).voidreset()Rewinds to the first frame: how the engine loops a stream seamlessly.intdefault voidseek(long micros) Moves tomicrosso that the nextreadFrames(short[], int)returns audio from there: how a track follows a video that has been seeked, and how a transport control moves a long piece of music without restarting it.
-
Method Details
-
channels
int channels()- Returns:
- 1 (mono) or 2 (stereo, interleaved)
-
sampleRate
int sampleRate()- Returns:
- frames per second (e.g. 44100)
-
readFrames
int readFrames(short[] out, int maxFrames) Decodes up tomaxFramesframes intoout(interleaved,frames × channelsshorts from index 0).- Returns:
- the number of frames written;
0means end of stream
-
reset
void reset()Rewinds to the first frame: how the engine loops a stream seamlessly. -
seek
default void seek(long micros) Moves tomicrosso that the nextreadFrames(short[], int)returns audio from there: how a track follows a video that has been seeked, and how a transport control moves a long piece of music without restarting it.Repositioning the source is only half of a seek. The engine has already handed whole buffers to the device, and those play out before anything read after this does, so a caller that moves the source and nothing else hears the old position for the depth of the queue and then a jump.
Playback.seek(long)is the operation that does both, and it is what a caller wants; this is what the engine calls underneath it.Accuracy is the implementation's: a decoder that can only reach a packet boundary lands on one. A target beyond the end leaves the track at its end, where
readFrames(short[], int)reports zero; a target at or below zero is the beginning.Called on the thread
readFrames(short[], int)is called on and never concurrently with it.- Parameters:
micros- where to move to, in microseconds from the start of the track; not negative- Throws:
UnsupportedOperationException- ifcanSeek()is falseIllegalArgumentException- ifmicrosis negative
-
canSeek
default boolean canSeek()- Returns:
- whether
seek(long)works, which defaults to false so that a source written before seeking existed keeps telling the truth. Independent ofreset(), which every source supports: rewinding to the start is not the same capability as reaching the middle.
-
close
void close()Releases decoder/file resources. Idempotent.- Specified by:
closein interfaceAutoCloseable
-