/** * 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} - 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} - 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} - Resolves with audio data */ async generateSpeech(text, options = {}) { // To be implemented by subclasses return { success: false, reason: 'not_implemented' }; } }