From 85f41756d18d586377823eaac26117f3c8ccb9ba Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sat, 28 Feb 2026 23:58:54 +0100 Subject: feat: changelog page --- apps/web/content/changelog/0.2.0.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 apps/web/content/changelog/0.2.0.md (limited to 'apps/web/content/changelog/0.2.0.md') diff --git a/apps/web/content/changelog/0.2.0.md b/apps/web/content/changelog/0.2.0.md new file mode 100644 index 00000000..ec3a99e2 --- /dev/null +++ b/apps/web/content/changelog/0.2.0.md @@ -0,0 +1,13 @@ +--- +version: "0.2.0" +date: "2026-02-29" +title: "Motion & Effects" +description: "This release adds the foundation for motion and effects." +changes: + - type: new + text: "Keyframe animation system, starting with transform properties (position, scale, rotation)." + - type: new + text: "Effects system (with our first effect: Blur!)" + - type: fixed + text: "Fixed an issue where click-and-drag selection on one timeline track could accidentally select items from the track below." +--- -- cgit v1.3.1 From c6bffaa243795ce47273dc60ee98abaf272d2d35 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 1 Mar 2026 01:10:56 +0100 Subject: fix(audio): stabilize playback startup when timeline selection is heavy --- apps/web/content/changelog/0.2.0.md | 2 ++ apps/web/src/core/managers/audio-manager.ts | 42 ++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) (limited to 'apps/web/content/changelog/0.2.0.md') diff --git a/apps/web/content/changelog/0.2.0.md b/apps/web/content/changelog/0.2.0.md index ec3a99e2..0539be78 100644 --- a/apps/web/content/changelog/0.2.0.md +++ b/apps/web/content/changelog/0.2.0.md @@ -10,4 +10,6 @@ changes: text: "Effects system (with our first effect: Blur!)" - type: fixed text: "Fixed an issue where click-and-drag selection on one timeline track could accidentally select items from the track below." + - type: fixed + text: "Audio could flicker or cut out at the start of playback when certain elements were selected. The scheduler now recovers from timing slips without losing audio." --- diff --git a/apps/web/src/core/managers/audio-manager.ts b/apps/web/src/core/managers/audio-manager.ts index 457e49d6..20b124b6 100644 --- a/apps/web/src/core/managers/audio-manager.ts +++ b/apps/web/src/core/managers/audio-manager.ts @@ -29,6 +29,7 @@ export class AudioManager { private playbackSessionId = 0; private lastIsPlaying = false; private lastVolume = 1; + private playbackLatencyCompensationSeconds = 0; private unsubscribers: Array<() => void> = []; constructor(private editor: EditorCore) { @@ -136,6 +137,7 @@ export class AudioManager { this.stopPlayback(); this.playbackSessionId++; + this.playbackLatencyCompensationSeconds = 0; const tracks = this.editor.timeline.getTracks(); const mediaAssets = this.editor.media.getAssets(); @@ -224,13 +226,21 @@ export class AudioManager { const clipStart = clip.startTime; const clipEnd = clip.startTime + clip.duration; - - const iteratorStartTime = Math.max(startTime, clipStart); + const playbackTimeAfterSinkReady = this.getPlaybackTime(); + const iteratorStartTime = Math.max( + startTime, + clipStart, + playbackTimeAfterSinkReady, + ); + if (iteratorStartTime >= clipEnd) { + return; + } const sourceStartTime = clip.trimStart + (iteratorStartTime - clip.startTime); const iterator = sink.buffers(sourceStartTime); this.clipIterators.set(clip.id, iterator); + let consecutiveDroppedBufferCount = 0; for await (const { buffer, timestamp } of iterator) { if (!this.editor.playback.getIsPlaying()) return; @@ -244,15 +254,41 @@ export class AudioManager { node.connect(this.masterGain ?? audioContext.destination); const startTimestamp = - this.playbackStartContextTime + (timelineTime - this.playbackStartTime); + this.playbackStartContextTime + + this.playbackLatencyCompensationSeconds + + (timelineTime - this.playbackStartTime); if (startTimestamp >= audioContext.currentTime) { node.start(startTimestamp); + consecutiveDroppedBufferCount = 0; } else { const offset = audioContext.currentTime - startTimestamp; if (offset < buffer.duration) { node.start(audioContext.currentTime, offset); + consecutiveDroppedBufferCount = 0; } else { + consecutiveDroppedBufferCount += 1; + if (consecutiveDroppedBufferCount >= 5) { + const nextCompensationSeconds = Math.max( + this.playbackLatencyCompensationSeconds, + Math.min(0.25, offset + 0.01), + ); + if ( + nextCompensationSeconds > + this.playbackLatencyCompensationSeconds + 0.001 + ) { + this.playbackLatencyCompensationSeconds = + nextCompensationSeconds; + } + const resyncStartTime = this.getPlaybackTime(); + this.clipIterators.delete(clip.id); + void this.runClipIterator({ + clip, + startTime: resyncStartTime, + sessionId, + }); + return; + } continue; } } -- cgit v1.3.1 From 354f4dec67ef7eb39d34fca941ca34025a68136b Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 1 Mar 2026 01:12:57 +0100 Subject: changelog: update titles for no title case --- apps/web/content/changelog/0.1.0.md | 2 +- apps/web/content/changelog/0.2.0.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apps/web/content/changelog/0.2.0.md') diff --git a/apps/web/content/changelog/0.1.0.md b/apps/web/content/changelog/0.1.0.md index d1c21bf0..08a0a9ed 100644 --- a/apps/web/content/changelog/0.1.0.md +++ b/apps/web/content/changelog/0.1.0.md @@ -1,7 +1,7 @@ --- version: "0.1.0" date: "2026-02-23" -title: "Editor Foundation" +title: "Editor foundation" description: "This first release focuses on making editing faster, clearer, and more reliable for day-to-day use." changes: - type: new diff --git a/apps/web/content/changelog/0.2.0.md b/apps/web/content/changelog/0.2.0.md index 0539be78..ea69f78b 100644 --- a/apps/web/content/changelog/0.2.0.md +++ b/apps/web/content/changelog/0.2.0.md @@ -1,7 +1,7 @@ --- version: "0.2.0" date: "2026-02-29" -title: "Motion & Effects" +title: "Motion & effects" description: "This release adds the foundation for motion and effects." changes: - type: new -- cgit v1.3.1