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/
SpeechSynthesizer.cpp@1:a2bd45c3b373, 2015-11-07 (annotated)
- Committer:
- ksekimoto
- Date:
- Sat Nov 07 12:29:06 2015 +0000
- Revision:
- 1:a2bd45c3b373
- Parent:
- 0:40a09c55e5be
To call Azure Marketplace Translation (and Speech) service.; The first version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ksekimoto | 0:40a09c55e5be | 1 | //////////////////////////////////////////////////////////////////////////// |
ksekimoto | 0:40a09c55e5be | 2 | // Licensed under the Apache License, Version 2.0 (the "License"); |
ksekimoto | 0:40a09c55e5be | 3 | // you may not use this file except in compliance with the License. |
ksekimoto | 0:40a09c55e5be | 4 | // You may obtain a copy of the License at |
ksekimoto | 0:40a09c55e5be | 5 | // |
ksekimoto | 0:40a09c55e5be | 6 | // http://www.apache.org/licenses/LICENSE-2.0 |
ksekimoto | 0:40a09c55e5be | 7 | // |
ksekimoto | 0:40a09c55e5be | 8 | // Unless required by applicable law or agreed to in writing, software |
ksekimoto | 0:40a09c55e5be | 9 | // distributed under the License is distributed on an "AS IS" BASIS, |
ksekimoto | 0:40a09c55e5be | 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ksekimoto | 0:40a09c55e5be | 11 | // See the License for the specific language governing permissions and |
ksekimoto | 0:40a09c55e5be | 12 | // limitations under the License. |
ksekimoto | 0:40a09c55e5be | 13 | // |
ksekimoto | 0:40a09c55e5be | 14 | // Copyright (c) Microsoft Corporation. All rights reserved. |
ksekimoto | 0:40a09c55e5be | 15 | // Portions Copyright (c) Kentaro Sekimoto All rights reserved. |
ksekimoto | 0:40a09c55e5be | 16 | // |
ksekimoto | 0:40a09c55e5be | 17 | // Based on Text-To-Speech for .NET Micro Framework with Microsoft |
ksekimoto | 0:40a09c55e5be | 18 | // Translator Service |
ksekimoto | 0:40a09c55e5be | 19 | // https://code.msdn.microsoft.com/Text-To-Speech-for-NET-9cea4462 |
ksekimoto | 0:40a09c55e5be | 20 | // |
ksekimoto | 0:40a09c55e5be | 21 | //////////////////////////////////////////////////////////////////////////// |
ksekimoto | 0:40a09c55e5be | 22 | |
ksekimoto | 0:40a09c55e5be | 23 | #include "mbed.h" |
ksekimoto | 0:40a09c55e5be | 24 | #include "SpeechSynthesizer.h" |
ksekimoto | 0:40a09c55e5be | 25 | #include "AdmAuthentication.h" |
ksekimoto | 0:40a09c55e5be | 26 | #include "HTTPClient.h" |
ksekimoto | 0:40a09c55e5be | 27 | #include "HTTPFile.h" |
ksekimoto | 0:40a09c55e5be | 28 | #include "USBHostMSD.h" |
ksekimoto | 0:40a09c55e5be | 29 | #include "string.h" |
ksekimoto | 0:40a09c55e5be | 30 | |
ksekimoto | 0:40a09c55e5be | 31 | #define MAX_STREAM (256*256*16) |
ksekimoto | 0:40a09c55e5be | 32 | #define BASE_URL "http://api.microsofttranslator.com/v2/Http.svc/" |
ksekimoto | 0:40a09c55e5be | 33 | #define AUTHORIZATION_HEADER "Authorization" |
ksekimoto | 0:40a09c55e5be | 34 | #define AUDIOFORMAT "audio/wav" |
ksekimoto | 0:40a09c55e5be | 35 | #define AUDIOQUALITY "MinSize" // "MaxQuality" |
ksekimoto | 0:40a09c55e5be | 36 | #define LANGUAGE "en" |
ksekimoto | 0:40a09c55e5be | 37 | //#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" |
ksekimoto | 0:40a09c55e5be | 38 | |
ksekimoto | 0:40a09c55e5be | 39 | static char url[1024]; |
ksekimoto | 0:40a09c55e5be | 40 | static char encoded_text[1024]; |
ksekimoto | 0:40a09c55e5be | 41 | static char encoded_format[32]; |
ksekimoto | 0:40a09c55e5be | 42 | static char encoded_language[32]; |
ksekimoto | 0:40a09c55e5be | 43 | static char buf[MAX_STREAM]; |
ksekimoto | 0:40a09c55e5be | 44 | static HTTPText inText(buf, MAX_STREAM); |
ksekimoto | 0:40a09c55e5be | 45 | static char header[1024]; |
ksekimoto | 0:40a09c55e5be | 46 | static char encoded_from[256]; |
ksekimoto | 0:40a09c55e5be | 47 | static char encoded_to[256]; |
ksekimoto | 0:40a09c55e5be | 48 | static char translated[256]; |
ksekimoto | 0:40a09c55e5be | 49 | |
ksekimoto | 0:40a09c55e5be | 50 | void urlencode(char *src, char *dst) |
ksekimoto | 0:40a09c55e5be | 51 | { |
ksekimoto | 0:40a09c55e5be | 52 | int c; |
ksekimoto | 0:40a09c55e5be | 53 | char *hex = "0123456789ABCDEF"; |
ksekimoto | 0:40a09c55e5be | 54 | |
ksekimoto | 0:40a09c55e5be | 55 | while( (c = *src++) != 0 ){ |
ksekimoto | 0:40a09c55e5be | 56 | if( ('a' <= c && c <= 'z') |
ksekimoto | 0:40a09c55e5be | 57 | || ('A' <= c && c <= 'Z') |
ksekimoto | 0:40a09c55e5be | 58 | || ('0' <= c && c <= '9') ){ |
ksekimoto | 0:40a09c55e5be | 59 | *dst++ = c; |
ksekimoto | 0:40a09c55e5be | 60 | } else { |
ksekimoto | 0:40a09c55e5be | 61 | *dst++ = '%'; |
ksekimoto | 0:40a09c55e5be | 62 | *dst++ = hex[c >> 4]; |
ksekimoto | 0:40a09c55e5be | 63 | *dst++ = hex[c & 15]; |
ksekimoto | 0:40a09c55e5be | 64 | } |
ksekimoto | 0:40a09c55e5be | 65 | } |
ksekimoto | 0:40a09c55e5be | 66 | } |
ksekimoto | 0:40a09c55e5be | 67 | |
ksekimoto | 0:40a09c55e5be | 68 | void SpeechSynthesizer::UpdateToken() |
ksekimoto | 0:40a09c55e5be | 69 | { |
ksekimoto | 0:40a09c55e5be | 70 | char *ptoken; |
ksekimoto | 0:40a09c55e5be | 71 | printf("UpdateToken...\r\n"); |
ksekimoto | 0:40a09c55e5be | 72 | AdmAuthentication auth = AdmAuthentication(id, secret); |
ksekimoto | 0:40a09c55e5be | 73 | ptoken = auth.GetAccessToken(); |
ksekimoto | 0:40a09c55e5be | 74 | sprintf(token, "Bearer %s", ptoken); |
ksekimoto | 0:40a09c55e5be | 75 | } |
ksekimoto | 0:40a09c55e5be | 76 | |
ksekimoto | 0:40a09c55e5be | 77 | void SpeechSynthesizer::GetSpeakStream(char *filename, char *text, char *language) |
ksekimoto | 0:40a09c55e5be | 78 | { |
ksekimoto | 0:40a09c55e5be | 79 | printf("GetSpeakStream...\r\n"); |
ksekimoto | 0:40a09c55e5be | 80 | HTTPClient hc; |
ksekimoto | 0:40a09c55e5be | 81 | HTTPFile inFile(filename); |
ksekimoto | 0:40a09c55e5be | 82 | urlencode(text, encoded_text); |
ksekimoto | 0:40a09c55e5be | 83 | urlencode(audioFormat, encoded_format); |
ksekimoto | 0:40a09c55e5be | 84 | urlencode(language, encoded_language); |
ksekimoto | 0:40a09c55e5be | 85 | sprintf(url, "%sSpeak?text=%s&language=%s&format=%s&options=%s", |
ksekimoto | 0:40a09c55e5be | 86 | BASE_URL, encoded_text, encoded_language, encoded_format, audioQuality); |
ksekimoto | 0:40a09c55e5be | 87 | #ifdef DEBUG_SPEECH |
ksekimoto | 0:40a09c55e5be | 88 | printf("url:%s\r\n", url); |
ksekimoto | 0:40a09c55e5be | 89 | #endif |
ksekimoto | 0:40a09c55e5be | 90 | #ifndef TEST_TOKEN |
ksekimoto | 0:40a09c55e5be | 91 | sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, token); |
ksekimoto | 0:40a09c55e5be | 92 | #else |
ksekimoto | 0:40a09c55e5be | 93 | sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, TEST_TOKEN); |
ksekimoto | 0:40a09c55e5be | 94 | #endif |
ksekimoto | 0:40a09c55e5be | 95 | #ifdef DEBUG_SPEECH |
ksekimoto | 0:40a09c55e5be | 96 | printf("header:%s\r\n", header); |
ksekimoto | 0:40a09c55e5be | 97 | #endif |
ksekimoto | 0:40a09c55e5be | 98 | hc.setHeader(header); |
ksekimoto | 0:40a09c55e5be | 99 | hc.get((const char*)url, &inFile, 10000); |
ksekimoto | 0:40a09c55e5be | 100 | inFile.close(); |
ksekimoto | 0:40a09c55e5be | 101 | } |
ksekimoto | 0:40a09c55e5be | 102 | |
ksekimoto | 0:40a09c55e5be | 103 | char *SpeechSynthesizer::Translate(char *from, char *to) |
ksekimoto | 0:40a09c55e5be | 104 | { |
ksekimoto | 0:40a09c55e5be | 105 | printf("Translate...\r\n"); |
ksekimoto | 0:40a09c55e5be | 106 | HTTPClient hc; |
ksekimoto | 0:40a09c55e5be | 107 | urlencode(from, encoded_from); |
ksekimoto | 0:40a09c55e5be | 108 | urlencode(to, encoded_to); |
ksekimoto | 0:40a09c55e5be | 109 | sprintf(url, "%sTranslate?text=%s&to=%s&contentType=text/plain", |
ksekimoto | 0:40a09c55e5be | 110 | BASE_URL, encoded_from, encoded_to); |
ksekimoto | 0:40a09c55e5be | 111 | #ifdef DEBUG_SPEECH |
ksekimoto | 0:40a09c55e5be | 112 | printf("url:%s\r\n", url); |
ksekimoto | 0:40a09c55e5be | 113 | #endif |
ksekimoto | 0:40a09c55e5be | 114 | #ifndef TEST_TOKEN |
ksekimoto | 0:40a09c55e5be | 115 | sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, token); |
ksekimoto | 0:40a09c55e5be | 116 | #else |
ksekimoto | 0:40a09c55e5be | 117 | sprintf(header, "%s: %s\r\n", AUTHORIZATION_HEADER, TEST_TOKEN); |
ksekimoto | 0:40a09c55e5be | 118 | #endif |
ksekimoto | 0:40a09c55e5be | 119 | hc.setHeader(header); |
ksekimoto | 0:40a09c55e5be | 120 | hc.get((const char*)url, &inText, 10000); |
ksekimoto | 0:40a09c55e5be | 121 | char *pTokenStart = strstr(buf, ">"); |
ksekimoto | 0:40a09c55e5be | 122 | if (pTokenStart == NULL) { |
ksekimoto | 0:40a09c55e5be | 123 | return (char *)NULL; |
ksekimoto | 0:40a09c55e5be | 124 | } |
ksekimoto | 0:40a09c55e5be | 125 | pTokenStart += 1; |
ksekimoto | 0:40a09c55e5be | 126 | char *pTokenEnd = strstr(pTokenStart, "<"); |
ksekimoto | 0:40a09c55e5be | 127 | if (pTokenEnd == NULL) { |
ksekimoto | 0:40a09c55e5be | 128 | return (char *)NULL; |
ksekimoto | 0:40a09c55e5be | 129 | } |
ksekimoto | 0:40a09c55e5be | 130 | strncpy(translated, pTokenStart, (pTokenEnd - pTokenStart)); |
ksekimoto | 0:40a09c55e5be | 131 | translated[pTokenEnd - pTokenStart] = 0; |
ksekimoto | 0:40a09c55e5be | 132 | printf("%s -> %s\r\n", from, translated); |
ksekimoto | 0:40a09c55e5be | 133 | return (char *)translated; |
ksekimoto | 0:40a09c55e5be | 134 | } |
ksekimoto | 0:40a09c55e5be | 135 | |
ksekimoto | 0:40a09c55e5be | 136 | SpeechSynthesizer::SpeechSynthesizer(const char *clientID, const char *clientSecret) |
ksekimoto | 0:40a09c55e5be | 137 | { |
ksekimoto | 0:40a09c55e5be | 138 | id = (char *)clientID; |
ksekimoto | 0:40a09c55e5be | 139 | secret = (char *)clientSecret; |
ksekimoto | 0:40a09c55e5be | 140 | language = (char *)LANGUAGE; |
ksekimoto | 0:40a09c55e5be | 141 | audioFormat = (char *)AUDIOFORMAT; |
ksekimoto | 0:40a09c55e5be | 142 | audioQuality = (char *)AUDIOQUALITY; |
ksekimoto | 0:40a09c55e5be | 143 | } |
ksekimoto | 0:40a09c55e5be | 144 | |
ksekimoto | 0:40a09c55e5be | 145 | SpeechSynthesizer::~SpeechSynthesizer() |
ksekimoto | 0:40a09c55e5be | 146 | { |
ksekimoto | 0:40a09c55e5be | 147 | } |
ksekimoto | 0:40a09c55e5be | 148 |