To call Azure Marketplace Translation (and Speech) service

Dependencies:   EthernetInterface-FRDM HTTPClient-SSL R_BSP SDFileSystem TLV320_RBSP USBHost mbed-rtos mbed-src

The program calls Azure Marketplace Translation (and Speech) service.

How to use - Create an account for Microsoft Azure Marketplace - Get client ID and client secret. - Change client ID and client secret in main.cpp

The program was created based on the following libraries.

CodePlex Text-To-Speech with Microsoft Translator Service http://translatorservice.codeplex.com/

MBED HTTPClient-SSL Library https://developer.mbed.org/teams/MultiTech/code/HTTPClient-SSL/

/media/uploads/ksekimoto/gr-peach_cloud_speech_01.jpg

SpeechSynthesizer.cpp

Committer:
ksekimoto
Date:
2015-11-07
Revision:
1:a2bd45c3b373
Parent:
0:40a09c55e5be

File content as of revision 1:a2bd45c3b373:

////////////////////////////////////////////////////////////////////////////
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//  Portions Copyright (c) Kentaro Sekimoto All rights reserved.
//
//  Based on Text-To-Speech for .NET Micro Framework with Microsoft 
//  Translator Service
//  https://code.msdn.microsoft.com/Text-To-Speech-for-NET-9cea4462
//
////////////////////////////////////////////////////////////////////////////

#include "mbed.h"
#include "SpeechSynthesizer.h"
#include "AdmAuthentication.h"
#include "HTTPClient.h"
#include "HTTPFile.h"
#include "USBHostMSD.h"
#include "string.h"

#define MAX_STREAM  (256*256*16)
#define BASE_URL    "http://api.microsofttranslator.com/v2/Http.svc/"
#define AUTHORIZATION_HEADER    "Authorization"
#define AUDIOFORMAT     "audio/wav"
#define AUDIOQUALITY    "MinSize"       // "MaxQuality"
#define LANGUAGE    "en"
//#define TEST_TOKEN  "Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=netmf_speech&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&Audience=http%3a%2f%2fapi.microsofttranslator.com&ExpiresOn=1446517938&Issuer=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&HMACSHA256=h%2bgxg4uaVMnlB8PYzFhCn9Q2KGPtE2%2bwZHuseh2nQxY%3d"

static char url[1024];
static char encoded_text[1024];
static char encoded_format[32];
static char encoded_language[32];
static char buf[MAX_STREAM];
static HTTPText inText(buf, MAX_STREAM);
static char header[1024];
static char encoded_from[256];
static char encoded_to[256];
static char translated[256];

void urlencode(char *src, char *dst)
{
    int c;
    char *hex = "0123456789ABCDEF";

    while( (c = *src++) != 0 ){
        if( ('a' <= c && c <= 'z')
        || ('A' <= c && c <= 'Z')
        || ('0' <= c && c <= '9') ){
            *dst++ = c;
        } else {
            *dst++ = '%';
            *dst++ = hex[c >> 4];
            *dst++ = hex[c & 15];
        }
    }
}

void SpeechSynthesizer::UpdateToken()
{
    char *ptoken;
    printf("UpdateToken...\r\n");
    AdmAuthentication auth = AdmAuthentication(id, secret);
    ptoken = auth.GetAccessToken();
    sprintf(token, "Bearer %s", ptoken);
}

void SpeechSynthesizer::GetSpeakStream(char *filename, char *text, char *language)
{
    printf("GetSpeakStream...\r\n");
    HTTPClient hc;
    HTTPFile inFile(filename);
    urlencode(text, encoded_text);
    urlencode(audioFormat, encoded_format);
    urlencode(language, encoded_language);
    sprintf(url, "%sSpeak?text=%s&language=%s&format=%s&options=%s", 
        BASE_URL, encoded_text, encoded_language, encoded_format, audioQuality);
#ifdef DEBUG_SPEECH
    printf("url:%s\r\n", url);
#endif
#ifndef TEST_TOKEN
    sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, token);
#else
    sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, TEST_TOKEN);
#endif
#ifdef DEBUG_SPEECH
    printf("header:%s\r\n", header);
#endif
    hc.setHeader(header);
    hc.get((const char*)url, &inFile, 10000);
    inFile.close();
}

char *SpeechSynthesizer::Translate(char *from, char *to)
{
    printf("Translate...\r\n");
    HTTPClient hc;
    urlencode(from, encoded_from);
    urlencode(to, encoded_to);
    sprintf(url, "%sTranslate?text=%s&to=%s&contentType=text/plain", 
        BASE_URL, encoded_from, encoded_to);
#ifdef DEBUG_SPEECH
    printf("url:%s\r\n", url);
#endif
#ifndef TEST_TOKEN
    sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, token);
#else
    sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, TEST_TOKEN);
#endif
    hc.setHeader(header);
    hc.get((const char*)url, &inText, 10000);
    char *pTokenStart = strstr(buf, ">");
    if (pTokenStart == NULL) {
        return (char *)NULL;
    }
    pTokenStart += 1;
    char *pTokenEnd = strstr(pTokenStart, "<");
    if (pTokenEnd == NULL) {
        return (char *)NULL;
    }
    strncpy(translated, pTokenStart, (pTokenEnd - pTokenStart));
    translated[pTokenEnd - pTokenStart] = 0;
    printf("%s -> %s\r\n", from, translated);
    return (char *)translated;
}
    
SpeechSynthesizer::SpeechSynthesizer(const char *clientID, const char *clientSecret)
{
    id = (char *)clientID;
    secret = (char *)clientSecret; 
    language = (char *)LANGUAGE;
    audioFormat = (char *)AUDIOFORMAT;
    audioQuality = (char *)AUDIOQUALITY;
}

SpeechSynthesizer::~SpeechSynthesizer()
{
}