Checkpoint current interactive fiction state

This commit is contained in:
2026-05-14 21:17:43 +02:00
parent c745efd1d2
commit 873049f7e6
183 changed files with 13755 additions and 1459 deletions
+47 -5
View File
@@ -20,6 +20,12 @@ export class KokoroTTSModule extends TTSHandlerModule {
this.lastProgressTime = null;
this.lastProgressValue = null;
this.modelLoaded = false;
// Options for playback
this.options = {
volume: 1.0,
rate: 1.0
};
// Bind additional methods beyond those in TTSHandlerModule
this.bindMethods([
@@ -30,7 +36,8 @@ export class KokoroTTSModule extends TTSHandlerModule {
'preprocessText',
'pause',
'resume',
'getDefaultVoices'
'getDefaultVoices',
'setVoiceOptions'
]);
}
@@ -51,6 +58,16 @@ export class KokoroTTSModule extends TTSHandlerModule {
console.error('Kokoro TTS: Required dependency persistence-manager not found');
return false;
}
const ttsEnabled = persistenceManager.getPreference('tts', 'enabled', false);
const preferredHandler = persistenceManager.getPreference('tts', 'preferred_handler', 'none');
if (!ttsEnabled || preferredHandler !== this.id) {
this.voices = this.getDefaultVoices();
this.isReady = false;
this.reportProgress(100, 'Kokoro TTS not selected');
console.log('Kokoro TTS: Skipping model load because provider is not selected');
return true;
}
// Try to check if the kokoro-js.js resource exists before proceeding
try {
@@ -206,9 +223,11 @@ export class KokoroTTSModule extends TTSHandlerModule {
if (!event.data.success || event.data.error) {
resolver.reject(new Error(event.data.error || 'Speech generation failed'));
} else {
const audioData = event.data.result && event.data.result.buffer;
console.log('Kokoro: Generation complete, audioData:', audioData ? `${audioData.byteLength} bytes` : 'UNDEFINED');
resolver.resolve({
success: true,
audioData: event.data.result && event.data.result.buffer,
audioData: audioData,
duration: event.data.duration || 0
});
}
@@ -333,6 +352,21 @@ export class KokoroTTSModule extends TTSHandlerModule {
return true;
}
setVoiceOptions(options = {}) {
if (options.voice) {
const voice = this.voices.find(v => v.id === options.voice) || { id: options.voice };
this.setVoice(voice);
}
if (typeof options.speed === 'number') {
this.setOptions({ rate: Math.max(0.5, Math.min(2.0, options.speed)) });
}
if (typeof options.volume === 'number') {
this.setOptions({ volume: Math.max(0, Math.min(1, options.volume)) });
}
}
/**
* Get available voices
@@ -435,7 +469,11 @@ export class KokoroTTSModule extends TTSHandlerModule {
// Start playback
this.currentAudio = audio;
this.isSpeaking = true;
audio.play().catch(error => {
audio.play().then(() => {
document.dispatchEvent(new CustomEvent('tts:audio-started', {
detail: { provider: this.id || this.name }
}));
}).catch(error => {
this.isSpeaking = false;
if (callback) {
callback({ success: false, reason: 'playback_error', error });
@@ -498,7 +536,11 @@ export class KokoroTTSModule extends TTSHandlerModule {
// Start playback
this.currentAudio = audio;
this.isSpeaking = true;
audio.play().catch(error => {
audio.play().then(() => {
document.dispatchEvent(new CustomEvent('tts:audio-started', {
detail: { provider: this.id || this.name }
}));
}).catch(error => {
this.isSpeaking = false;
if (callback) {
callback({ success: false, reason: 'playback_error', error });
@@ -645,4 +687,4 @@ export class KokoroTTSModule extends TTSHandlerModule {
const kokoroTTSModule = new KokoroTTSModule();
export { kokoroTTSModule };
export { kokoroTTSModule };