MCPcopy Create free account
hub / github.com/stemdeckapp/stemdeck / _scheduleNext

Function _scheduleNext

static/js/chunkedAudioEngine.js:259–282  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

257 // --- lookahead scheduler ---
258
259 async function _scheduleNext() {
260 const chunkIdx = Math.floor(_scheduledTo / CHUNK_SEC);
261 _fetchChunk(chunkIdx + 1); // fire-and-forget pre-fetch of the chunk after
262
263 // Use the synchronous result if already decoded, otherwise await.
264 const hit = _cache.get(chunkIdx);
265 const buffers = hit?.result ?? await _fetchChunk(chunkIdx);
266 if (!playing || destroyed) return;
267 if (!buffers || buffers.size === 0) return; // past end; tick() handles onEnded
268
269 // With SoundTouch, sources play at 1.0x so scheduled wall-clock time equals
270 // audio time. With tape-effect (_playbackRate != 1, no stNode), sources play
271 // faster/slower so wall-clock time = audio seconds / _playbackRate.
272 const playFactor = stNode ? 1.0 : _playbackRate;
273 const idealWhen = _startCtxTime + (_scheduledTo - _startOffset) / playFactor;
274 const when = Math.max(idealWhen, ctx.currentTime + 0.01);
275 // If we're late (slow network), skip the audio portion that already "passed".
276 const firstBuf = buffers.values().next().value;
277 const maxSkip = firstBuf ? Math.max(0, firstBuf.duration - 0.001) : 0;
278 const bufOffset = Math.min(Math.max(0, when - idealWhen) * playFactor, maxSkip);
279
280 const dur = _scheduleChunk(buffers, when, bufOffset);
281 _scheduledTo += bufOffset + dur; // always advances by ~CHUNK_SEC
282 }
283
284 function _maybeSchedule() {
285 if (_filling || !playing || destroyed) return;

Callers 1

_maybeScheduleFunction · 0.85

Calls 2

_fetchChunkFunction · 0.85
_scheduleChunkFunction · 0.85

Tested by

no test coverage detected