From aadf9e06df9f46415a90193a485e885a1f7db963 Mon Sep 17 00:00:00 2001 From: Xiaohan-Tian <157918347+Xiaohan-Tian@users.noreply.github.com> Date: Sun, 21 Dec 2025 18:51:20 -0800 Subject: [PATCH] feat: added lookAhead option --- public/config.json | 3 +- .../settings/sections/BehaviorSettings.tsx | 64 ++++++++++++++++++- src/core/audio-interface/KGAudioInterface.ts | 22 +++++++ src/core/config/ConfigManager.ts | 4 +- 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/public/config.json b/public/config.json index 2c60bbc..8d398c7 100644 --- a/public/config.json +++ b/public/config.json @@ -62,7 +62,8 @@ "default_open": true }, "audio": { - "enable_audio_capture_for_screen_sharing": false + "enable_audio_capture_for_screen_sharing": false, + "lookahead_time": 0.05 }, "templates": { "custom_instructions": "" diff --git a/src/components/settings/sections/BehaviorSettings.tsx b/src/components/settings/sections/BehaviorSettings.tsx index 82fa4c5..02b7b25 100644 --- a/src/components/settings/sections/BehaviorSettings.tsx +++ b/src/components/settings/sections/BehaviorSettings.tsx @@ -1,9 +1,12 @@ import React, { useState, useEffect } from 'react'; import { ConfigManager } from '../../../core/config/ConfigManager'; +import { KGAudioInterface } from '../../../core/audio-interface/KGAudioInterface'; const BehaviorSettings: React.FC = () => { const [chatboxDefaultOpen, setChatboxDefaultOpen] = useState(true); + const [audioLookaheadTime, setAudioLookaheadTime] = useState('50'); const [enableAudioCapture, setEnableAudioCapture] = useState(false); + const [validationErrors, setValidationErrors] = useState([]); const configManager = ConfigManager.instance(); @@ -15,6 +18,8 @@ const BehaviorSettings: React.FC = () => { } setChatboxDefaultOpen((configManager.get('chatbox.default_open') as boolean) ?? true); + const lookaheadTimeSeconds = (configManager.get('audio.lookahead_time') as number) ?? 0.05; + setAudioLookaheadTime(((lookaheadTimeSeconds * 1000).toFixed(0))); setEnableAudioCapture((configManager.get('audio.enable_audio_capture_for_screen_sharing') as boolean) ?? false); }; @@ -28,6 +33,36 @@ const BehaviorSettings: React.FC = () => { await configManager.set('chatbox.default_open', boolValue); }; + const handleAudioLookaheadTimeChange = async (value: string) => { + // Allow empty string, treat as 0 ms + const numValueMs = value === '' ? 0 : parseFloat(value); + const numValueSeconds = numValueMs / 1000; + const errors: string[] = []; + + // Validate the input + if (isNaN(numValueMs)) { + errors.push('Lookahead time must be a valid number'); + } else if (numValueSeconds < 0) { + errors.push('Lookahead time must be between 0 and 0.5 seconds (0-500ms)'); + } else if (numValueSeconds > 0.5) { + errors.push('Lookahead time must be between 0 and 0.5 seconds (0-500ms)'); + } + + setValidationErrors(errors); + + // Only apply if valid + if (errors.length === 0) { + setAudioLookaheadTime(value); + await configManager.set('audio.lookahead_time', numValueSeconds); + + // Apply the change immediately without restart + const audioInterface = KGAudioInterface.instance(); + audioInterface.setLookaheadTime(numValueSeconds); + + console.log(`Audio lookahead time changed to: ${numValueSeconds}s (${numValueMs}ms)`); + } + }; + const handleEnableAudioCaptureChange = async (value: string) => { const boolValue = value === 'yes'; setEnableAudioCapture(boolValue); @@ -61,7 +96,34 @@ const BehaviorSettings: React.FC = () => {

Audio

- + +
+ + handleAudioLookaheadTimeChange(e.target.value)} + min="0" + max="500" + step="1" + /> + {validationErrors.length > 0 && ( +
+ {validationErrors.map((error, index) => ( +
+ {error} +
+ ))} +
+ )} +
+ Audio scheduling lookahead time (0-500ms). Lower values (10-20ms) reduce MIDI input latency but may cause audio glitches on slower systems. Higher values (100ms+) are better for playback stability. Changes apply immediately without restart. +
+
+