Text-to-speech

For the Audio Write test step and the interactive test execution a text-to-speech-service can be configured. Each service can define multiple different voices. By default ecu.test supports speech output using the SAPI of Windows. It is possible to connect or implement additional text-to-speech services using UserPyModules.

User defined speech output

The speech output uses a text-to-speech service to generate a audio file from a given text and parameters. This file will then be replayed to the audio output device. A Python script needs to fulfill several requirements to be available as a valid speech output.

  • The script needs to be located in the UserPyModules folder of the workspace.

  • On the top level of the script, you must specify the variable MODULE_TYPE = ‘TextToSpeechService’.

  • The file needs to contain a class “TextToSpeechService”.

  • The class needs to implement the methods __init__, GetVoices, SpeakToFile, GetCapabilities, GetFileExtension and GetServiceId.

  • There must not be two services with the same service ID.

  • Voices within the service can be identified uniquely by their name, language and gender.

Newly added services are available after refreshing the user libraries. You can do this in ecu.test in the menu “Extras”.

Minimal TextToSpeechService Example

This is an example of a user defined speech output.

import numpy as np
import wave

MODULE_TYPE = 'TextToSpeechService'


class TextToSpeechService:
    """
    Test TextToSpeechService that only implements a parameterized sine curve instead of a
    speech output.
    """

    def __init__(self):
        pass

    def GetVoices(self) -> list[tuple[str, str, str]]:
        """
        Returns list of available voices as triple (name, language, gender)
        """
        return [
            ('Harald', 'de', 'MALE'),
            ('Harold', 'en', 'MALE'),
            ('Brigitte', 'de', 'FEMALE'),
            ('Robot', 'en', 'OTHER'),
        ]

    def _GetVoiceFreq(self, voice: str) -> float:
        match voice:
            case 'Harald':
                return 440.
            case 'Harold':
                return 600.
            case 'Brigitte':
                return 1000.
            case 'Robot':
                return 110.

        return 10

    def SpeakToFile(self,
                    text: str,
                    voice: tuple[str, str, str],
                    filePath: str,
                    parameters: dict) -> None:
        """
        This method generates a speech output for the specified text and parameters
        (speed and pitch) with the specified voice (name, language, gender) under the specified
        file path. That file will be used for audio output.
        """
        volume = 0.5
        sampleRate = 48000
        duration = (len(text) / 10.) * parameters['speed']
        f = self._GetVoiceFreq(voice[0]) * parameters['pitch']

        # generate samples
        samples = (np.sin(2 * np.pi * np.arange(sampleRate * duration) * f / sampleRate)).astype(
            np.float32)

        output_bytes = (volume * samples).tobytes()

        with wave.open(filePath, 'wb') as wavefile:
            wavefile.setnchannels(1)
            wavefile.setsampwidth(4)
            wavefile.setframerate(sampleRate)
            wavefile.writeframes(output_bytes)

    @staticmethod
    def GetCapabilities() -> list[str]:
        """
        Marks if UserTextToSpeechService module supports pitch and speed adaptation.
        """
        return ['pitch', 'speed']

    @staticmethod
    def GetFileExtension() -> str:
        """
        Extension of generated speech audio files.
        """
        return 'wav'

    @staticmethod
    def GetServiceId() -> str:
        """
        Service name as to be displayed in the voice selection.
        """
        return "FakeTTS"

Explanation of available Methods

Class “TextToSpeechService”

This class must be implemented by the Python script.

__init__

This method needs to be implemented without arguments, but may be empty.

GetVoices

This method returns a list of voices that are available for the text-to-speech service. Each voice is listed as a triple (name, RFC 5646 language code, gender).

SpeakToFile

This method generated the speech output file

  • for the requested text

  • in the selected voice of the module, given as triple (name, language, gender).

  • The audio output needs to be saved as a file in the defined filePath.

  • The parameter dictionary may contain information on ‘speed’ and ‘pitch’. They can be taken into account during the generation of the audio output. Speed and pitch can be altered from ecu.test once they have been marked as supported by the text-to-speech service using the GetCapabilities() method.

GetCapabilities

This method returns the information, if pitch and speed can be parameterized for this text-to-speech module.

GetFileExtension

Returns the file extension of the created audio file. This information is needed because the temporary file path for the speech output for each run is defined by ecu.test.

GetServiceId

Unique identifier of the text-to-speech service.