Loupe

[Oxford Project] Text To Speech via Azure

 

Depuis quelques mois, un projet de Microsoft Research permet d’effectuer d’effectuer des traitements sur le son, telles que la reconnaissance vocale, en se basant sur des algorithmes puissants.

La feature la plus facile à prendre en main pour débuter avec le projet Oxford est le TTS ou Text To Speech permettant de convertir un texte en un audio en déléguant le traitement à un service Azure.

Voyons comment procéder.

 

1. Création du service Azure Oxford

Voici le point d’entrée pour la partie Speech du projet Oxford https://www.projectoxford.ai/speech

Celui-ci va en réalité vous renvoyer vers Azure pour créer le service adapté.

Voici donc un résumé des étapes :

image

Une fois votre service créé, pensez à récupérer les clés “clientId” et “clientSecret” qui nous seront nécessaires par la suite. Pour le faire, suivez ce petit lien dans la page de gestion de votre service : image

 

 

2. Créer le client C#

Microsoft fournit un SDK. Cool ! On a rien à coder alors ? Malheureusement le seul SDK dispo pour le moment est pour… Android. ET oui, on va tout refaire à la main alors. Go !

2.1 Authentification

Pour utiliser le service Oxford, votre programme doit pouvoir s'authentifier auprès de celui-ci.

Nous allons donc commencer par créer une classe Authentication dont le but sera de gérer l'authentification.

Pour cela, trois données seront nécessaires : le clientId, le clientSecret et bien sûr, l'url du service.

Une simple requête HTTP POST utilisant ces paramètres permet de faire le boulot.

Voici donc un extrait du code vous permettant de créer la classe Authentication :

public static readonly string AccessUri = "https://oxford-speech.cloudapp.net/token/issueToken";

            //Create the request to get token from service

            var request = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope={2}",

                Uri.EscapeUriString(clientId),

                Uri.EscapeUriString(clientSecret),

                Uri.EscapeUriString("https://speech.platform.bing.com"));

            var httpClient = new HttpClient();

            byte[] bytes = Encoding.ASCII.GetBytes(request);

            HttpContent httpContent = new ByteArrayContent(bytes);

            httpContent.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            //Send the request and extract token

            var result = httpClient.PostAsync(accessUri, httpContent).Result;

            result.EnsureSuccessStatusCode();

            var stream = result.Content.ReadAsStreamAsync().Result;

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AccessTokenInfo));

            //Get deserialized object from JSON stream

            AccessTokenInfo token = (AccessTokenInfo)serializer.ReadObject(stream);

            //return the created token

            return token;

Bien évidemment, je vous invite à sauvegarder les clés et le token et de mettre en place un système de renouvèlement du token lorsque celui-ci arrive à expiration (toutes les 10 minutes).

2.2. Appel du service Azure

Pour appeler le service Oxford, il nous faut déjà connaitre son url que voici : https://speech.platform.bing.com/synthesize

Ensuite, il nous faut connaitre les paramètres nécessaires pour nous faire comprendre du service :

· Le texte

· Le type de voix (male, female)

· La "locale" utilisée (ex: fr-FR)

· Le nom de la voix à utiliser : "Microsoft Server Speech Text to Speech Voice (fr-FR, Julie, Apollo)"

· Le format de sortie (ex: "riff-16khz-16bit-mono-pcm")

· Le token d'authentification au format "Bearer " + le token généré dans l'étape précédente

Pour la plupart des paramètres, la documentation du service vous aidera à connaitre les possibilités qui vous sont offertes.

Dans un premier temps nous allons donc créer le client HTTP et initialiser l'Uri que nous allons utiliser :

var requestUri = new Uri(requestUri);

Pour communiquer avec le service nous devons donc passer certains de ces paramètres dans le header de la requête :

List<KeyValuePair<string, string>> headers = new List<KeyValuePair<string, string>>();

 headers.Add(new KeyValuePair<string, string>("Content-Type", "application/ssml+xml"));
headers.Add(new KeyValuePair<string, string>("X-Microsoft-OutputFormat", "riff-16khz-16bit-mono-pcm"));

// authorization Header

headers.Add(new KeyValuePair<string, string>("Authorization", this.AuthorizationToken));

// ClientID and Client Secret from Azure Oxford Speech Service

headers.Add(new KeyValuePair<string, string>("X-Search-AppId", "**************"));
headers.Add(new KeyValuePair<string, string>("X-Search-ClientID", "**************"));

// The software originating the request

headers.Add(new KeyValuePair<string, string>("User-Agent", "TTSClient"));

Ce qui nous donne ensuite, pour la création de la requête :

var client = new HttpClient();

// Ajout des paramêtres dans le header :

foreach (var header in headers)

            {

                client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);

            }
var content = new StringContent(String.Format(SsmlTemplate, locale, genderValue, voiceName, textToTranslate));

var response = await client.PostAsync(requestUri, content);

Stream httpStream = await response.Content.ReadAsStreamAsync();


 

3. Jouer ou sauvegarder le son

Pour jouer le fichier son généré par le service depuis votre application, vous n'aurez donc plus qu'à appeler une méthode exploitant le stream comme celle-ci :

static void PlayAudio(object sender, GenericEventArgs<Stream> args)

        {

            Console.WriteLine(args.EventData);

            // For SoundPlayer to be able to play the wav file, it has to be encoded in PCM.

            // Use output audio format AudioOutputFormat.Riff16Khz16BitMonoPcm to do that.

            SoundPlayer player = new SoundPlayer(args.EventData);

            player.PlaySync();

            args.EventData.Dispose();

}

En revanche vous n'aurez pas forcément envie de lire le son depuis l'application l'ayant généré. Dans ce cas-là le stream pourra être sauvegardé.

Vous devrez reconstruire un fichier au format wav que vous pourrez alors sauvegarder dans votre bibliothèque Musique par exemple :

private static async void SaveAudio(object sender, Stream stream)

{

            var folder = KnownFolders.MusicLibrary;

            StorageFile file = await folder.CreateFileAsync("music\\meteo.wav", CreationCollisionOption.ReplaceExisting);

            using (Stream fileStream = await file.OpenStreamForWriteAsync())

            {

                const int BUFFER_SIZE = 1024;

                byte[] buf = new byte[BUFFER_SIZE];

                int bytesread = 0;

                while ((bytesread = await stream.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)

                {

                   await fileStream.WriteAsync(buf, 0, bytesread);

                }

            }

            stream.Dispose();

        }

 

Have fun et à bientôt pour de la reconnaissance vocale !

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus