Instruções de uso

Essa seção apresenta as informações básicas de como utilizar o Texto Fala em uma aplicação C/C++. Detalhes sobre as funções da API pública podem ser consultados acessando a seção Interface de Programação ou através dos hiperlinks presentes no texto.

O código fonte dos exemplos de uso da biblioteca em C/C++ está disponível publicamente no GitHub: https://github.com/CPqD/tts-examples-c.

Inicialização do Texto Fala

O primeiro passo para usar o Texto Fala é carregar a biblioteca dinâmica. O carregamento da biblioteca é feito dinamicamente através das funções dlopen (ambientes baseados em Unix) ou LoadLibrary (ambientes Windows). O programa de exemplo que acompanha o pacote de instalação do Texto Fala inclui funções para o carregamento e descarregamento da biblioteca dinâmica nos dois ambientes.

Após carregada a biblioteca, deve-se inicializar o Texto Fala antes de poder executar qualquer operação. A inicialização é feita através da função TTS_Initialize, que requer dois parâmetros: o caminho onde o produto está instalado e o caminho onde os arquivos de log serão gerados.

result = TTS_Initialize("/opt/cpqd/tts/engine", "/var/log/tts");
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X na inicialização\n", result);
    exit(EXIT_FAILURE);
}

Aviso

A inicialização do Texto Fala pode ser um processo custoso, dependendo das vozes configuradas no arquivo tts.conf, e só precisa ser feita apenas uma única vez. Não inicialize o produto várias vezes durante a execução da aplicação, pois isso causará lentidão.

Se algum problema ocorrer durante a inicialização, a função TTS_Initialize retornará um código de erro. Detalhes do erro podem ser obtidos no arquivo de log tts.log. Também é possível invocar a função TTS_GetLastError para obter detalhes do erro em tempo de execução, conforme apresentado na seção Tratamento de erros.

Quando a aplicação não precisar mais utilizar o Texto Fala, use a função TTS_Terminate para finalizar o produto e liberar os recursos alocados.

Gerenciamento de vozes

Para utilizar as funções de síntese, é necessário ter uma ou mais vozes carregadas. Normalmente o arquivo tts.conf vem configurado para carregar todas as vozes adquiridas durante a inicializaçao, mas em determinados cenários pode ser interessante carregar a voz apenas quando necessária (e.g. para economizar memória). Nesses casos, a aplicação pode fazer uso da função TTS_LoadVoice para carregar uma voz em tempo de execução.

Aviso

Dependendo do tipo de voz, o carregamento pode ser um processo custoso e causará em lentidão. Em geral, vozes do tipo compact são as mais rápidas de carregar e as do tipo highquality são as mais demoradas. Carregar as vozes na inicialização é a melhor opção na maioria dos cenários.

A voz carregada será identificada pelo seu nome de arquivo. Por exemplo, se o programa invocar a função indicando o caminho /opt/cpqd/tts/engine/rosana-compact.voice, a voz será identificada pela expressão rosana-compact.voice.

TTS_RETURN result;

result = TTS_LoadVoice("/opt/cpqd/tts/engine/rosana-compact.voice");
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X ao carregar a voz\n", result);
}

Uma vez carregada, a voz estará disponível para uso até que seja explicitamente descarregada por meio da função TTS_UnloadVoice ou até a finalização do Texto Fala.

TTS_RETURN result;

result = TTS_UnloadVoice("rosana-compact.voice");
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X ao descarregar a voz\n", result);
}

Sessões de síntese

Antes de utilizar as funções de síntese, uma sessão deve ser criada. Uma sessão define um contexto no qual pode-se parametrizar e efetuar uma síntese de fala. As sessões são thread-safe e é recomendado que uma sessão seja utilizada por apenas uma thread.

As sessões são criadas através da função TTS_CreateSession, que fornece para a aplicação um identificador. Esse identificador será utilizado por todas as funções que utilizam sessões de síntese. Ao invocar a função TTS_CreateSession, a aplicação pode indicar o nome da voz padrão. A voz padrão é aquela que será utilizada quando nenhuma outra for especificada via SSML.

TTS_RETURN result;
TTS_HANDLE handle;

// cria uma sessão sem definir a voz padrão (será usada
// a voz padrão do arquivo de configuração)
result = TTS_CreateSession(NULL, &handle);
if (result != TTS_OK)
{
    main_printError("TTS_CreateSession");
    exit(EXIT_FAILURE);
}

As configurações iniciais de uma sessão de síntese vem do arquivo de configuração. Quando a sessão é criada, o Texto Fala recupera os parâmetros definidos no arquivo de configuração (e.g. codificação do áudio, ritmo, etc) e aplica-os na sessão. Entretanto, a aplicação pode alterar esses parâmetros para cada sessão utilizando funções da API. A tabela a seguir lista as funções que permitem recuperar e alterar as configurações em tempo de execução. A lista dos parâmetros existentes pode ser conferida no Apêndice II – Parâmetros de configuração.

Recuperar

Alterar

O exemplo a seguir aumenta o ritmo da fala em 20% e altera a codificação do áudio de saída para: PCM linear, 8kHz, 16 bits por amostra, mono.

result = TTS_SetFloatParameter(handle, TTS_PARAM_RATE, 1.2);
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X ao alterar parâmetro\n", result);
}

result = TTS_SetStringParameter(handle, TTS_PARAM_ENCODER, "pcm/8000/16/1");
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X ao alterar parâmetro\n", result);
}

É importante destacar que sessões de síntese são recursos limitados e devem ser liberadas quando não forem mais necessárias. A liberação de uma sessão é feita através da função TTS_ReleaseSession.

result = TTS_ReleaseSession(handle);
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X ao liberar a sessão\n", result);
}

Conversão de texto em fala

A conversão de texto em fala pode ser realizada através de duas funções: TTS_TextToSpeech e TTS_TextToSpeechStream.

A função TTS_TextToSpeech oferece a forma mais simples de efetuar a conversão de texto em fala, na qual função bloqueará a thread corrente até que todo o texto tenha sido convertido. Quando a função retornar, a aplicação poderá recuperar o áudio gerado usando a função TTS_CopyAudio ou armazená-lo em disco com a função TTS_SaveAudio.

result = TTS_TextToSpeech(handle, "Este é um exemplo de síntese de fala");
if (result == TTS_OK)
    TTS_SaveAudio(handle, "saida.wav");

Já a função TTS_TextToSpeechStream converte texto em fala via streaming. Nesse modo de operação, a aplicação recebe porções do áudio gerado na medida em que a síntese de fala é efetuada. A entrega do áudio é realizada em blocos via função de callback e o tamanho dos blocos é variável. Esse modo de operação é bastante útil em aplicações onde o tempo de resposta é um fator crítico, como em cenários envolvendo diálogo em tempo real.

uint8_t receivedAudio( TTS_HANDLE handle,
    const TTS_STREAM_EVENT *event, void *data )
{
    if (event->Audio != NULL)
        printf("Recebidos %d bytes de áudio\n", event->Audio->Length);
}

...

TTS_RETURN result;

result = TTS_TextToSpeechStream(handle, "Este é um exemplo de síntese de fala",
    receivedAudio, NULL);
if (result != TTS_OK)
{
    printf("Ocorreu o erro 0x%04X ao converter texto em fala\n", result);
}

Note que a função TTS_TextToSpeechStream não efetua síntese de forma assíncrona: a função também bloqueia a thread corrente até o final da conversão de texto em fala, mas oferece um meio da aplicação obter resultados parciais. Idealmente, a aplicação deveria criar uma thread separada para invocar a função TTS_TextToSpeechStream de forma que a interface com o usuário não seja comprometida.

Após a execução da função TTS_TextToSpeechStream, o áudio também estará disponível para ser recuperado pelas funções TTS_CopyAudio e TTS_SaveAudio.

Tratamento de erros

Em caso de falha na execução de alguma operação, as funções do Texto Fala irão retornar um código de erro. Os códigos de erro fornecem uma visão geral a respeito da falha ocorrida. Caso seja necessário obter maiores detalhes, seja para incluir em arquivos de log da aplicação ou fornecer para a equipe de suporte do CPQD, pode-se fazer uso da função TTS_GetLastError.

TTS_ERROR_INFO *info = NULL;
TTS_RETURN result;

result = TTS_GetLastError(&info);
if (result != TTS_OK)
{
    printf("Erro 0x%04X: %s\n", info->Code, info->Message);
    TTS_Free(info);
}