def calculate_word_times(self, alignment_info: Mapping[str, Any]) -> List[Tuple[str, float]]:
        """Calculate word timing from character alignment data.

        Example input data:
        {
            "characters": [" ", "H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"],
            "character_start_times_seconds": [0.0, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
            "character_end_times_seconds": [0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
        }

        Would produce word times (with cumulative_time=0):
        [("Hello", 0.1), ("world", 0.5)]

        Args:
            alignment_info: Character timing data from ElevenLabs

        Returns:
            List of (word, timestamp) pairs
        """
        chars = alignment_info.get("characters", [])
        char_start_times = alignment_info.get("character_start_times_seconds", [])

        if not chars or not char_start_times or len(chars) != len(char_start_times):
            logger.warning(
                f"Invalid alignment data: chars={len(chars)}, times={len(char_start_times)}"
            )
            return []

        # Build the words and find their start times
        words = []
        word_start_times = []
        current_word = ""
        first_char_idx = -1

        for i, char in enumerate(chars):
            if char == " ":
                if current_word:  # Only add non-empty words
                    words.append(current_word)
                    # Use time of the first character of the word, offset by cumulative time
                    word_start_times.append(
                        self._cumulative_time + char_start_times[first_char_idx]
                    )
                    current_word = ""
                    first_char_idx = -1
            else:
                if not current_word:  # This is the first character of a new word
                    first_char_idx = i
                current_word += char

        # Don't forget the last word if there's no trailing space
        if current_word and first_char_idx >= 0:
            words.append(current_word)
            word_start_times.append(self._cumulative_time + char_start_times[first_char_idx])

        # Create word-time pairs
        word_times = list(zip(words, word_start_times))

        return word_times
Calculate word timing from character alignment data.

        Example input data:
        {
            "characters": [" ", "H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"],
            "character_start_times_seconds": [0.0, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
            "character_end_times_seconds": [0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
        }

        Would produce word times (with cumulative_time=0):
        [("Hello", 0.1), ("world", 0.5)]

        Args:
            alignment_info: Character timing data from ElevenLabs

        Returns:
            List of (word, timestamp) pairs
        
src/pipecat/services/elevenlabs/tts.py