203 lines
5.7 KiB
JavaScript
203 lines
5.7 KiB
JavaScript
/**
|
|
* TTSHandlerModule Base Class
|
|
* Base class for all TTS handler modules
|
|
*/
|
|
import { BaseModule } from './base-module.js';
|
|
|
|
export class TTSHandlerModule extends BaseModule {
|
|
constructor(id, name) {
|
|
super(id, name);
|
|
|
|
// Common TTS handler properties
|
|
this.isReady = false;
|
|
this.isSpeaking = false;
|
|
this.currentUtterance = null;
|
|
this.voices = [];
|
|
this.currentVoice = null;
|
|
this.defaultVoice = null;
|
|
this.speechRate = 1.0;
|
|
this.pitch = 1.0;
|
|
this.volume = 1.0;
|
|
|
|
// Common dependencies for TTS handlers
|
|
this.dependencies = ['persistence-manager', 'localization'];
|
|
|
|
// Bind common methods
|
|
this.bindMethods([
|
|
'speak',
|
|
'stop',
|
|
'getVoices',
|
|
'setVoice',
|
|
'configure',
|
|
'generateSpeech'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get the handler ID
|
|
* @returns {string} - The handler ID
|
|
*/
|
|
getId() {
|
|
return this.id;
|
|
}
|
|
|
|
/**
|
|
* Initialize the TTS handler
|
|
* @returns {Promise<boolean>} - Resolves with success status
|
|
*/
|
|
async initialize() {
|
|
try {
|
|
this.reportProgress(20, `Initializing ${this.name}`);
|
|
|
|
// Check for required dependencies
|
|
const persistenceManager = this.getModule('persistence-manager');
|
|
if (!persistenceManager) {
|
|
console.error(`${this.name}: Persistence Manager dependency not found`);
|
|
return false;
|
|
}
|
|
|
|
// Load preferences
|
|
this.loadPreferences(persistenceManager);
|
|
|
|
// Set up event listeners
|
|
this.setupEventListeners();
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error(`${this.name}: Initialization error`, error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load preferences from persistence manager
|
|
* @param {Object} persistenceManager - The persistence manager module
|
|
*/
|
|
loadPreferences(persistenceManager) {
|
|
// Load common preferences
|
|
this.speechRate = persistenceManager.getPreference('tts', 'rate', 1.0);
|
|
this.pitch = persistenceManager.getPreference('tts', 'pitch', 1.0);
|
|
this.volume = persistenceManager.getPreference('tts', 'volume', 1.0);
|
|
}
|
|
|
|
/**
|
|
* Set up common event listeners
|
|
*/
|
|
setupEventListeners() {
|
|
// To be implemented by subclasses if needed
|
|
}
|
|
|
|
/**
|
|
* Check if the handler is ready
|
|
* @returns {boolean} - Whether the handler is ready
|
|
*/
|
|
isHandlerReady() {
|
|
return this.isReady;
|
|
}
|
|
|
|
/**
|
|
* Check if the handler is currently speaking
|
|
* @returns {boolean} - Whether the handler is speaking
|
|
*/
|
|
isSpeakingNow() {
|
|
return this.isSpeaking;
|
|
}
|
|
|
|
/**
|
|
* Get available voices
|
|
* @returns {Promise<Array>} - Resolves with array of voice objects
|
|
*/
|
|
async getVoices() {
|
|
return this.voices;
|
|
}
|
|
|
|
/**
|
|
* Set the voice to use
|
|
* @param {string} voiceId - Voice identifier
|
|
* @returns {boolean} - Success status
|
|
*/
|
|
setVoice(voiceId) {
|
|
// To be implemented by subclasses
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Configure TTS parameters
|
|
* @param {Object} options - Configuration options
|
|
* @returns {boolean} - Success status
|
|
*/
|
|
configure(options) {
|
|
let changed = false;
|
|
|
|
if (options.voice && options.voice !== this.currentVoice) {
|
|
this.setVoice(options.voice);
|
|
changed = true;
|
|
}
|
|
|
|
if (options.speed && options.speed !== this.speechRate) {
|
|
this.speechRate = options.speed;
|
|
changed = true;
|
|
}
|
|
|
|
if (options.pitch && options.pitch !== this.pitch) {
|
|
this.pitch = options.pitch;
|
|
changed = true;
|
|
}
|
|
|
|
if (options.volume && options.volume !== this.volume) {
|
|
this.volume = options.volume;
|
|
changed = true;
|
|
}
|
|
|
|
// Save preferences if changed
|
|
if (changed) {
|
|
const persistenceManager = this.getModule('persistence-manager');
|
|
if (persistenceManager) {
|
|
persistenceManager.updatePreference('tts', 'rate', this.speechRate);
|
|
persistenceManager.updatePreference('tts', 'pitch', this.pitch);
|
|
persistenceManager.updatePreference('tts', 'volume', this.volume);
|
|
if (this.currentVoice) {
|
|
persistenceManager.updatePreference('tts', `${this.id}_voice`, this.currentVoice);
|
|
}
|
|
}
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
/**
|
|
* Speak text
|
|
* @param {string} text - Text to speak
|
|
* @param {Function} callback - Callback for when speech completes
|
|
* @returns {boolean} - Success status
|
|
*/
|
|
speak(text, callback) {
|
|
// To be implemented by subclasses
|
|
console.error(`${this.name}: speak() method not implemented`);
|
|
if (callback) {
|
|
setTimeout(() => callback({ success: false, reason: 'not_implemented' }), 0);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Stop speaking
|
|
* @returns {boolean} - Success status
|
|
*/
|
|
stop() {
|
|
// To be implemented by subclasses
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Generate speech audio data
|
|
* @param {string} text - Text to generate speech for
|
|
* @param {Object} options - Generation options
|
|
* @returns {Promise<Object>} - Resolves with audio data
|
|
*/
|
|
async generateSpeech(text, options = {}) {
|
|
// To be implemented by subclasses
|
|
return { success: false, reason: 'not_implemented' };
|
|
}
|
|
}
|