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

Files at this revision

API Documentation at this revision

Comitter:
ksekimoto
Date:
Sat Nov 07 12:21:19 2015 +0000
Child:
1:a2bd45c3b373
Commit message:
The frist version

Changed in this revision

AdmAuthentication.cpp Show annotated file Show diff for this revision Revisions of this file
AdmAuthentication.h Show annotated file Show diff for this revision Revisions of this file
EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClient-SSL.lib Show annotated file Show diff for this revision Revisions of this file
R_BSP.lib Show annotated file Show diff for this revision Revisions of this file
RomRamFileSystem.h Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
SpeechSynthesizer.cpp Show annotated file Show diff for this revision Revisions of this file
SpeechSynthesizer.h Show annotated file Show diff for this revision Revisions of this file
TLV320_RBSP.lib Show annotated file Show diff for this revision Revisions of this file
USBHost.lib Show annotated file Show diff for this revision Revisions of this file
dec_wav.h Show annotated file Show diff for this revision Revisions of this file
getline.cpp Show annotated file Show diff for this revision Revisions of this file
getline.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed-src.lib Show annotated file Show diff for this revision Revisions of this file
wavecnv.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AdmAuthentication.cpp	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,87 @@
+////////////////////////////////////////////////////////////////////////////
+//  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 "AdmAuthentication.h"
+#include "HTTPClient.h"
+
+#define MAX_DATAIN  1024
+#define DATAMARKET_ACCESS_URI "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"
+#define SCOPE   "http://api.microsofttranslator.com"
+#define HEADER  "application/x-www-form-urlencoded"
+#define TOKENTAG    "access_token"
+
+void urlencode(char *src, char *dst);
+
+static char datain[MAX_DATAIN];
+static HTTPText inText(datain, MAX_DATAIN);
+static char token_buf[MAX_DATAIN];
+
+char *AdmAuthentication::HttpPost(char *DatamarketAccessUri, char *requestDetails)
+{
+    HTTPClient hc;
+    HTTPText outText(requestDetails);
+    outText.setDataType(HEADER);
+#ifdef DEBUG_AUTH
+    printf("DatamarketAccessUri:%s\r\n", DatamarketAccessUri);
+    printf("requestDetails:%s\r\n", requestDetails);
+#endif
+    hc.post((const char*)DatamarketAccessUri, outText, &inText);
+#ifdef DEBUG_AUTH
+    printf("inText:%s\r\n", datain);
+#endif
+    char *pTokenStart = strstr(datain, TOKENTAG);
+    if (pTokenStart == NULL) {
+        return (char *)NULL;
+    }
+    pTokenStart += (strlen(TOKENTAG) + 3);
+    char *pTokenEnd = strstr(pTokenStart, "\"");
+    if (pTokenEnd == NULL) {
+        return (char *)NULL;
+    }
+    strncpy(token_buf, pTokenStart, (pTokenEnd - pTokenStart));
+    token_buf[pTokenEnd - pTokenStart] = 0;
+#ifdef DEBUG_AUTH
+    printf("access_token:%s\r\n", token_buf);
+#endif
+    return (char *)token_buf;
+}
+
+char *AdmAuthentication::GetAccessToken()
+{
+    return HttpPost((char *)DATAMARKET_ACCESS_URI, request);
+}
+
+AdmAuthentication::AdmAuthentication(char *clientID, char *clientSecret)
+{
+    char encoded_scope[64]; 
+    id = clientID;
+    secret = clientSecret;
+    urlencode(id, encoded_id);
+    urlencode(secret, encoded_secret);
+    urlencode(SCOPE, encoded_scope);
+    sprintf(request, "grant_type=client_credentials&client_id=%s&client_secret=%s&scope=%s", id, encoded_secret, SCOPE);
+}
+
+AdmAuthentication::~AdmAuthentication()
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AdmAuthentication.h	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////
+//  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"
+
+class AdmAuthentication
+{
+public:
+    AdmAuthentication(char *clientID, char *clientSecret);
+    ~AdmAuthentication();
+    char *GetAccessToken();
+    char *HttpPost(char *DatamarketAccessUri, char *requestDetails);
+    
+private:
+    char *id;
+    char *secret;
+    char encoded_id[64];
+    char encoded_secret[64];
+    char request[256];
+    char token[1024];
+    char url[128];
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/wolfSSL/code/EthernetInterface-FRDM/#4c9bfb661297
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPClient-SSL.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/MultiTech/code/HTTPClient-SSL/#7fbf8ef951f2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/R_BSP.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/Renesas/code/R_BSP/#aa1fc6a5cc2a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RomRamFileSystem.h	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,147 @@
+/*******************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only
+* intended for use with Renesas products. No other uses are authorized. This
+* software is owned by Renesas Electronics Corporation and is protected under
+* all applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
+* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
+* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
+* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
+* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
+* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
+* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software
+* and to discontinue the availability of this software. By using this software,
+* you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer*
+* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
+*******************************************************************************/
+#ifndef MBED_ROMRAMFILESYSTEM_H
+#define MBED_ROMRAMFILESYSTEM_H
+
+#include "FATFileSystem.h"
+
+#define NUM_OF_SECTORS     (1000)
+#define SECTOR_SIZE        (512)
+
+#if defined(TARGET_RZ_A1H)
+#define ROM_START_ADDRESS  (0x18000000uL)  // for GR-PEACH
+#define ROM_END_ADDRESS    (0x1FFFFFFFuL)  // for GR-PEACH
+#else
+#define ROM_START_ADDRESS  (0xFFFFFFFFuL)
+#define ROM_END_ADDRESS    (0xFFFFFFFFuL)
+#endif
+
+using namespace mbed;
+
+class RomRamFileSystem : public FATFileSystem {
+public:
+    // NUM_OF_SECTORS sectors, each 512 bytes
+    char *sectors[NUM_OF_SECTORS];
+
+    RomRamFileSystem(const char* name) : FATFileSystem(name) {
+        memset(sectors, 0, sizeof(sectors));
+    }
+
+    virtual ~RomRamFileSystem() {
+        for (int i = 0; i < NUM_OF_SECTORS; i++) {
+            if ((sectors[i] != NULL) && (isRomAddress(sectors[i]) == false)) {
+                free(sectors[i]);
+            }
+        }
+    }
+
+    // read a sector in to the buffer, return 0 if ok
+    virtual int disk_read(uint8_t *buffer, uint64_t sector, uint8_t count) {
+        for (uint64_t sec_no = sector; sec_no < (sector + count); sec_no++) {
+            if (sectors[sec_no] == NULL) {
+                // nothing allocated means sector is empty
+                memset(buffer, 0, SECTOR_SIZE);
+            } else {
+                memcpy(buffer, sectors[sec_no], SECTOR_SIZE);
+            }
+            buffer += SECTOR_SIZE;
+        }
+        return 0;
+    }
+
+    // write a sector from the buffer, return 0 if ok
+    virtual int disk_write(const uint8_t *buffer, uint64_t sector, uint8_t count) {
+        for (uint64_t sec_no = sector; sec_no < (sector + count); sec_no++) {
+            bool all_zero = true;
+            for (int i = 0; i < SECTOR_SIZE; i++) {
+                if (buffer[i] != NULL) {
+                    all_zero = false;
+                    break;
+                }
+            }
+            if (all_zero != false) {
+                if (sectors[sec_no] != NULL) {
+                    if (isRomAddress(sectors[sec_no]) == false) {
+                        free(sectors[sec_no]);
+                    }
+                    sectors[sec_no] = NULL;
+                }
+                return 0;
+            }
+            // allocate a sector if needed, and write
+            if (isRomAddress((char *)buffer) == false) {
+                if ((sectors[sec_no] == NULL) || (isRomAddress(sectors[sec_no]) != false)) {
+                    char *sec = (char*)malloc(SECTOR_SIZE);
+                    if (sec == NULL) {
+                        return 1; // out of memory
+                    }
+                    sectors[sec_no] = sec;
+                }
+                memcpy(sectors[sec_no], buffer, SECTOR_SIZE);
+            } else {
+                if (isRomAddress(sectors[sec_no]) == false) {
+                    free(sectors[sec_no]);
+                }
+                sectors[sec_no] = (char *)buffer;
+            }
+            buffer += SECTOR_SIZE;
+        }
+        return 0;
+    }
+
+    // return the number of sectors
+    virtual uint64_t disk_sectors() {
+        return NUM_OF_SECTORS;
+    }
+
+    void dump(FILE *fp) {
+        for (int i = 0; i < NUM_OF_SECTORS; i++) {
+            fwrite(&sectors[i], sizeof(int), 1, fp);
+            if (sectors[i] != NULL) {
+                fwrite(sectors[i], sizeof(char), SECTOR_SIZE, fp);
+            }
+        }
+    }
+
+    void load(FILE *fp) {
+        int sec_info = 0;
+        for (int i = 0; i < NUM_OF_SECTORS; i++) {
+            fread(&sec_info, sizeof(int), 1, fp);
+            if (sec_info != 0) {
+                char *sec = (char *)malloc(SECTOR_SIZE);
+                fread(sec, sizeof(char), SECTOR_SIZE, fp);
+                sectors[i] = sec;
+            }
+        }
+    }
+
+private:
+    bool isRomAddress(char * address) {
+        if (((uint32_t)address >= ROM_START_ADDRESS)
+         && ((uint32_t)address <= (ROM_END_ADDRESS - SECTOR_SIZE + 1))) {
+            return true;
+        }
+        return false;
+    }
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SpeechSynthesizer.cpp	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,148 @@
+////////////////////////////////////////////////////////////////////////////
+//  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()
+{
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SpeechSynthesizer.h	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,40 @@
+////////////////////////////////////////////////////////////////////////////
+//  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"
+
+class SpeechSynthesizer
+{
+public:
+    SpeechSynthesizer(const char *clientID, const char *clientSecret);
+    void GetSpeakStream(char *filename, char *text, char *language);
+    void UpdateToken();
+    char *Translate(char *text, char *to);
+    ~SpeechSynthesizer();
+private:
+    char *id;
+    char *secret;
+    char *language;
+    char *audioFormat;
+    char *audioQuality;
+    char token[512];
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLV320_RBSP.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/Renesas/code/TLV320_RBSP/#85f5b81eddea
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHost.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/USBHost/#0675edbac47d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dec_wav.h	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,252 @@
+/**************************************************************************//**
+* @file          dec_wav.h
+* @brief         wav
+******************************************************************************/
+#include "mbed.h"
+
+/** A class to communicate a dec_wav
+ *
+ */
+class dec_wav {
+public:
+
+    /** analyze header
+     *
+     * @param p_title title tag buffer
+     * @param p_artist artist tag buffer
+     * @param p_album album tag buffer
+     * @param tag_size tag buffer size
+     * @param fp file pointer
+     * @return true = success, false = failure
+     */
+    bool AnalyzeHeder(uint8_t * p_title, uint8_t * p_artist, uint8_t * p_album, uint16_t tag_size, FILE * fp) {
+        bool result = false;
+        size_t read_size;
+        uint8_t wk_read_buff[36];
+        uint8_t *data;
+        uint32_t chunk_size;
+        uint32_t sub_chunk_size;
+        uint32_t list_index_max;
+        bool list_ok = false;
+        uint32_t read_index = 0;
+        uint32_t data_index = 0;
+        uint16_t wk_len;
+
+        if (fp == NULL) {
+            return false;
+        }
+        music_data_size  = 0;
+        music_data_index = 0;
+        wav_fp = fp;
+        if (p_title != NULL) {
+            p_title[0] = '\0';
+        }
+        if (p_artist != NULL) {
+            p_artist[0] = '\0';
+        }
+        if (p_album != NULL) {
+            p_album[0] = '\0';
+        }
+
+        read_size = fread(&wk_read_buff[0], sizeof(char), 36, wav_fp);
+        if (read_size < 36) {
+            // do nothing
+        } else if (memcmp(&wk_read_buff[0], "RIFF", 4) != 0) {
+            // do nothing
+        } else if (memcmp(&wk_read_buff[8], "WAVE", 4) != 0) {
+            // do nothing
+        } else if (memcmp(&wk_read_buff[12], "fmt ", 4) != 0) {
+            // do nothing
+        } else {
+            read_index += 36;
+            channel = ((uint32_t)wk_read_buff[22] << 0) + ((uint32_t)wk_read_buff[23] << 8);
+            sampling_rate = ((uint32_t)wk_read_buff[24] << 0)
+                          + ((uint32_t)wk_read_buff[25] << 8)
+                          + ((uint32_t)wk_read_buff[26] << 16)
+                          + ((uint32_t)wk_read_buff[27] << 24);
+            block_size = ((uint32_t)wk_read_buff[34] << 0) + ((uint32_t)wk_read_buff[35] << 8);
+            while (1) {
+                //printf("dev_wav1\r\n");
+                read_size = fread(&wk_read_buff[0], sizeof(char), 8, wav_fp);
+                read_index += 8;
+                if (read_size < 8) {
+                    break;
+                } else {
+                    chunk_size = ((uint32_t)wk_read_buff[4] << 0)
+                               + ((uint32_t)wk_read_buff[5] << 8)
+                               + ((uint32_t)wk_read_buff[6] << 16)
+                               + ((uint32_t)wk_read_buff[7] << 24);
+                    if (memcmp(&wk_read_buff[0], "data", 4) == 0) {
+                        result = true;
+                        music_data_size = chunk_size;
+                        if (list_ok == true) {
+                            break;
+                        } else {
+                            data_index = read_index;
+                            fseek(wav_fp, chunk_size, SEEK_CUR);
+                            read_index += chunk_size;
+                        }
+                        //printf("dev_wav2\r\n");
+                    } else if (memcmp(&wk_read_buff[2], "data", 4) == 0) {
+                        read_index += 2;
+                        chunk_size = ((uint32_t)wk_read_buff[6] << 0)
+                                + ((uint32_t)wk_read_buff[7] << 8);
+                        result = true;
+                        music_data_size = chunk_size;
+                        if (list_ok == true) {
+                            break;
+                        } else {
+                            data_index = read_index;
+                            fseek(wav_fp, chunk_size, SEEK_CUR);
+                            read_index += chunk_size;
+                        }                    
+                    } else if (memcmp(&wk_read_buff[0], "LIST", 4) == 0) {
+                        list_ok = true;
+                        list_index_max = read_index + chunk_size;
+                        read_size = fread(&wk_read_buff[0], sizeof(char), 4, wav_fp);
+                        read_index += 4;
+                        while (read_index < list_index_max) {
+                            read_size = fread(&wk_read_buff[0], sizeof(char), 8, wav_fp);
+                            read_index += 8;
+                            if (read_size < 8) {
+                                break;
+                            } else if (memcmp(&wk_read_buff[0], "INAM", 4) == 0) {
+                                data = p_title;
+                            } else if (memcmp(&wk_read_buff[0], "IART", 4) == 0) {
+                                data = p_artist;
+                            } else if (memcmp(&wk_read_buff[0], "IPRD", 4) == 0) {
+                                data = p_album;
+                            } else {
+                                data = NULL;
+                            }
+                            if ((data != NULL) && (tag_size != 0)) {
+                                sub_chunk_size = ((uint32_t)wk_read_buff[4] << 0)
+                                               + ((uint32_t)wk_read_buff[5] << 8)
+                                               + ((uint32_t)wk_read_buff[6] << 16)
+                                               + ((uint32_t)wk_read_buff[7] << 24);
+                                if (sub_chunk_size > (tag_size - 1)) {
+                                    wk_len = (tag_size - 1);
+                                } else {
+                                    wk_len = sub_chunk_size;
+                                }
+                                read_size = fread(data, sizeof(char), wk_len, wav_fp);
+                                read_index += sub_chunk_size;
+                                fseek(wav_fp, read_index, SEEK_SET);
+                                data[wk_len] = '\0';
+                            }
+                        }
+                        if (data_index != 0) {
+                            break;
+                        } else {
+                            fseek(wav_fp, list_index_max, SEEK_SET);
+                        }
+                        //printf("dev_wav3\r\n");
+                    } else {
+                        fseek(wav_fp, chunk_size, SEEK_CUR);
+                        read_index += chunk_size;
+                        //printf("dev_wav4\r\n");
+                    }
+                }
+            }
+
+            if (data_index != 0) {
+                fseek(wav_fp, data_index, SEEK_SET);
+                //printf("dev_wav5\r\n");
+            }
+        }
+
+        return result;
+    };
+
+    /** get next data
+     *
+     * @param buf data buffer address
+     * @param len data buffer length
+     * @return get data size
+     */
+    size_t GetNextData(void *buf, size_t len) {
+        if (block_size == 24) {
+            // Add padding
+            int write_index = 0;
+            int wavfile_index;
+            int read_len;
+            int pading_index = 0;
+            uint8_t * p_buf = (uint8_t *)buf;
+            size_t ret;
+
+            if ((music_data_index + len) > music_data_size) {
+                len = music_data_size - music_data_index;
+            }
+            while (write_index < len) {
+                read_len = (len - write_index) * 3 / 4;
+                if (read_len > sizeof(wk_wavfile_buff)) {
+                    read_len = sizeof(wk_wavfile_buff);
+                }
+                music_data_index += read_len;
+                ret = fread(wk_wavfile_buff, sizeof(char), read_len, wav_fp);
+                if (ret < read_len) {
+                    break;
+                }
+                wavfile_index = 0;
+                while ((write_index < len) && (wavfile_index < read_len)) {
+                    if (pading_index == 0) {
+                        p_buf[write_index] = 0;
+                    } else {
+                        p_buf[write_index] = wk_wavfile_buff[wavfile_index];
+                        wavfile_index++;
+                    }
+                    if (pading_index < 3) {
+                        pading_index++;
+                    } else {
+                        pading_index = 0;
+                    }
+                    write_index++;
+                }
+            }
+
+            return write_index;
+        } else {
+            if ((music_data_index + len) > music_data_size) {
+                len = music_data_size - music_data_index;
+            }
+            music_data_index += len;
+
+            return fread(buf, sizeof(char), len, wav_fp);
+        }
+    };
+
+    /** get channel
+     *
+     * @return channel
+     */
+    uint16_t GetChannel() {
+        return channel;
+    };
+
+    /** get block size
+     *
+     * @return block size
+     */
+    uint16_t GetBlockSize() {
+        return block_size;
+    };
+
+    /** get sampling rate
+     *
+     * @return sampling rate
+     */
+    uint32_t GetSamplingRate() {
+        return sampling_rate;
+    };
+
+private:
+    #define FILE_READ_BUFF_SIZE    (3072)
+
+    FILE * wav_fp;
+    uint32_t music_data_size;
+    uint32_t music_data_index;
+    uint16_t channel;
+    uint16_t block_size;
+    uint32_t sampling_rate;
+    uint8_t wk_wavfile_buff[FILE_READ_BUFF_SIZE];
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getline.cpp	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,43 @@
+
+#include <mbed.h>
+
+int getline(char *prompt, char *buff, int size)
+{
+    int sz ;
+    
+    printf("%s", prompt) ;
+    for(sz = 0 ;  (sz < size) && ((*buff = getchar()) != '\r'); sz++, buff++) {
+        putchar(*buff) ;
+        if(*buff == '\\') {
+            if(++sz >= size)break ;
+            *buff = getchar() ;
+            putchar(*buff) ;
+            switch(*buff) {
+                case 'n' :
+                    *buff = '\n' ;
+                    break ;
+                case 'r' :
+                    *buff = '\r' ;
+                    break ;
+                case 't' :
+                    *buff = '\t' ;
+                    break ;
+                case '\\':
+                    *buff = '\\' ;
+                    break ;
+                default:
+                    buff[1] = buff[0] ;
+                    buff[0] = '\\' ;
+                    buff++ ;
+            }
+        } else if(*buff == '\b') {
+            if(sz >= 2) {
+                buff-=2 ;
+                sz-=2;
+            }
+        }
+    } ;
+    putchar('\n') ;
+    *buff = '\0' ;
+    return sz ;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getline.h	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+int getline(char *prompt, char *buff, int size) ;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,201 @@
+////////////////////////////////////////////////////////////////////////////
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "HTTPClient.h"
+#include "getline.h"
+#include "SpeechSynthesizer.h"
+#include "TLV320_RBSP.h"
+#include "dec_wav.h"
+#include "SDFileSystem.h"
+
+//#define SPEECH_TEXT "hello"
+#define SPEECH_TEXT "I will explain Cloud Speech Application."
+ 
+void wavecnv(char *fromfn, char *tofn);
+SDFileSystem sd(P8_5, P8_6, P8_3, P8_4, "sd");
+ 
+namespace {
+const char *sd_file_path = "/sd/out.txt";
+const int DATA_SIZE = 256;
+}
+
+#ifdef USBFS
+#include "USBHostMSD.h"
+#if defined(TARGET_RZ_A1H)
+#include "usb_host_setting.h"
+#else
+#define USB_HOST_CH     0
+#endif
+#if (USB_HOST_CH == 1) //Audio Shield USB1
+DigitalOut usb1en(P3_8);
+#endif
+#endif
+
+#ifdef ROMRAMFS
+#include "RomRamFileSystem.h"
+#endif
+
+#define AUDIO_WRITE_BUFF_SIZE  (4096)
+#define AUDIO_WRITE_BUFF_NUM   (9)
+#define FILE_NAME_LEN          (64)
+#define TEXT_SIZE              (64 + 1) //null-terminated
+
+#define CLIENT_ID       "xxxxxx"                        // need to register Azure
+#define CLIENT_SECRET   "yyyyyyyyyyyyyyyyyyyyyyyyyyyy"  // need to register Azure  
+#ifdef ROMRAMFS
+#define WAVE_MEM_FN "/romram/speech.wav"
+#endif
+#ifdef USBFS
+#define WAVE_USB_FN "/usb/speech.wav"
+#endif
+#define WAVE_SD_FN "/sd/speech8.wav"
+#define WAVE_SD_FN1 "/sd/speech16.wav"
+
+EthernetInterface eth;
+#ifdef USBFS
+USBHostMSD msd("usb");
+#endif
+#ifdef ROMRAMFS
+RomRamFileSystem romramfs("romram");
+#endif
+HTTPClient http;
+//char recvBuff[1024*20];
+      
+#ifdef ROMRAMFS  
+static void mount_romramfs(void) {
+    FILE * fp;
+    romramfs.format();
+}
+#endif
+
+static void callback_audio_write_end(void * p_data, int32_t result, void * p_app_data)
+{
+    if (result < 0) {
+        //printf("audio write callback error %d\n", result);
+    }
+}
+
+void wav_play(TLV320_RBSP *audio, char *filename)
+{
+//4 bytes aligned! No cache memory
+static uint8_t audio_write_buff[AUDIO_WRITE_BUFF_NUM][AUDIO_WRITE_BUFF_SIZE] __attribute((section("NC_BSS"),aligned(4)));
+static uint8_t title_buf[TEXT_SIZE];
+static uint8_t artist_buf[TEXT_SIZE];
+static uint8_t album_buf[TEXT_SIZE];
+
+    dec_wav wav_file;
+    size_t audio_data_size;
+    rbsp_data_conf_t audio_write_async_ctl = {&callback_audio_write_end, NULL};
+
+    FILE *fp = fopen(filename, "r");
+    if (fp == NULL) {
+        printf("Can't open %s\r\n", filename);
+        return;
+    } 
+    if (wav_file.AnalyzeHeder(title_buf, artist_buf, album_buf, TEXT_SIZE, fp) == false) {
+        printf("WAV format not supported. (%s)\r\n", filename);
+        printf("Error File  :%s\r\n", filename);
+        printf("Audio Info  :%dch, %dbit, %dHz\r\n", 
+            wav_file.GetChannel(), wav_file.GetBlockSize(), wav_file.GetSamplingRate());
+        fclose(fp);
+    } else if ((wav_file.GetChannel() != 2)
+        || (audio->format(wav_file.GetBlockSize()) == false)
+        || (audio->frequency(wav_file.GetSamplingRate()) == false)) {
+        printf("WAV format not supported. (%s)\r\n", filename);
+        printf("Audio Info  :%dch, %dbit, %dHz\r\n", 
+            wav_file.GetChannel(), wav_file.GetBlockSize(), wav_file.GetSamplingRate());
+        fclose(fp);
+    } else {
+        printf("File        :%s\r\n", filename);
+        printf("Audio Info  :%dch, %dbit, %dHz\r\n", 
+            wav_file.GetChannel(), wav_file.GetBlockSize(), wav_file.GetSamplingRate());
+        //printf("Title       :%s\r\n", title_buf);
+        //printf("Artist      :%s\r\n", artist_buf);
+        //printf("Album       :%s\r\n", album_buf);
+
+        int buff_index = 0;
+        while (1) {
+            uint8_t *p_buf = audio_write_buff[buff_index];
+            audio_data_size = wav_file.GetNextData(p_buf, AUDIO_WRITE_BUFF_SIZE);
+            if (audio_data_size > 0) {
+                audio->write(p_buf, audio_data_size, &audio_write_async_ctl);
+                buff_index++;
+            }
+            if (buff_index >= AUDIO_WRITE_BUFF_NUM) {
+                buff_index = 0;
+            }
+            if ((audio_data_size < AUDIO_WRITE_BUFF_SIZE)) {
+                break;
+            }
+        }
+        fclose(fp);
+    }    
+}
+
+void net_main(void const *av)
+{
+    int ret ;
+    char key[100] ;
+    char *translated;
+
+    eth.init(); //Use DHCP
+    printf("HTTP Client, Starting,...\r\n") ;
+    while(1) {
+        if(eth.connect() == 0)break ;
+        printf("Retry\n") ;
+    }
+    SpeechSynthesizer speech = SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
+    speech.UpdateToken();
+    translated = speech.Translate(SPEECH_TEXT, "ja");
+    speech.GetSpeakStream(WAVE_SD_FN, translated, "ja");
+    getline("Hit any key to start!\r\n", key, sizeof(key));
+    wavecnv(WAVE_SD_FN, WAVE_SD_FN1);
+    
+    TLV320_RBSP audio(P10_13, I2C_SDA, I2C_SCL, P4_4, P4_5, P4_7, P4_6, 0x80, (AUDIO_WRITE_BUFF_NUM - 1), 0);
+    audio.power(0x02); // mic off
+    audio.inputVolume(0.7, 0.7);
+    while(1) {
+        char key[10];
+        wav_play(&audio, WAVE_SD_FN1);
+        getline("Hit any key to start!\r\n", key, sizeof(key));
+    }
+}
+
+main()
+{
+#ifdef USBFS
+#if (USB_HOST_CH == 1) //Audio Shield USB1
+    //Audio Shield USB1 enable
+    usb1en = 1;        //Outputs high level
+    Thread::wait(5);
+    usb1en = 0;        //Outputs low level
+#endif
+    USBHostMSD msd("usb");
+#endif
+
+#ifdef ROMRAMFS
+    mount_romramfs();
+#endif
+#define STACK_SIZE 24000
+    Thread t(net_main, NULL, osPriorityNormal, STACK_SIZE);
+    while (true) {
+        Thread::wait(1000);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#5448826aa700
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src.lib	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-src/#a11c0372f0ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wavecnv.cpp	Sat Nov 07 12:21:19 2015 +0000
@@ -0,0 +1,114 @@
+////////////////////////////////////////////////////////////////////////////
+//  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.
+//
+//  Convert wave file from 8bit mono to 16 bit stereo
+//
+////////////////////////////////////////////////////////////////////////////
+
+#include "mbed.h"
+
+#define HEADER_SIZE 0x2e
+#define BUF_SIZE    1024
+#define TO_BUF_SIZE (FROM_BUF_SIZE * 2)
+#define MUL 20
+
+unsigned char fromHeader[HEADER_SIZE];
+unsigned char toHeader[HEADER_SIZE];
+
+unsigned char fromBuf[BUF_SIZE];
+short toBuf[BUF_SIZE*2];
+
+// 0x25c8 + 0x2e = 0x25f6
+void wavecnv(char *fromfn, char *tofn)
+{
+    FILE *fromfp;
+    FILE *tofp;
+    int fromSize;
+    int toSize;
+    unsigned int size;
+    int i;
+    unsigned int fromChunkSize;
+    unsigned int toChunkSize;
+    unsigned int sampleRate;
+    unsigned short uval;
+    short sval;
+    if ((fromfp = fopen(fromfn, "rb")) == NULL)
+        return;
+    if ((tofp = fopen(tofn, "wb")) == NULL)
+        return;
+    fromSize = fread(fromHeader, 1, HEADER_SIZE, fromfp);
+    memcpy(toHeader, fromHeader, HEADER_SIZE);
+    sampleRate = (unsigned int)fromHeader[0x18] +
+                    ((unsigned int)fromHeader[0x19] << 8) +
+                    ((unsigned int)fromHeader[0x1a] << 16) +
+                    ((unsigned int)fromHeader[0x1b] << 24) ;
+    sampleRate *= 4;
+    toHeader[0x1c] = (unsigned char)(sampleRate & 0xff);
+    toHeader[0x1d] = (unsigned char)((sampleRate >> 8) & 0xff);
+    toHeader[0x1e] = (unsigned char)((sampleRate >> 16) & 0xff);
+    toHeader[0x1f] = (unsigned char)((sampleRate >> 24) & 0xff);
+    toHeader[0x10] = 0x10;
+    toHeader[0x16] = 0x02;
+    toHeader[0x20] = 0x04;
+    toHeader[0x22] = 0x10;
+    fromChunkSize = (unsigned int)fromHeader[0x2a] +
+                    ((unsigned int)fromHeader[0x2b] << 8) +
+                    ((unsigned int)fromHeader[0x2c] << 16) +
+                    ((unsigned int)fromHeader[0x2d] << 24) ;
+    toChunkSize = fromChunkSize * 4;
+    toHeader[0x24] = 'd';
+    toHeader[0x25] = 'a';
+    toHeader[0x26] = 't';
+    toHeader[0x27] = 'a';
+    toHeader[0x28] = (unsigned char)(toChunkSize & 0xff);
+    toHeader[0x29] = (unsigned char)((toChunkSize >> 8) & 0xff);
+    toHeader[0x2a] = (unsigned char)((toChunkSize >> 16) & 0xff);
+    toHeader[0x2b] = (unsigned char)((toChunkSize >> 24) & 0xff);
+    size = toChunkSize + 0x2c - 8;
+    toHeader[0x04] = (unsigned char)(size & 0xff);
+    toHeader[0x05] = (unsigned char)((size >> 8) & 0xff);
+    toHeader[0x06] = (unsigned char)((size >> 16) & 0xff);
+    toHeader[0x07] = (unsigned char)((size >> 24) & 0xff);
+    toSize = fwrite(toHeader, 1, HEADER_SIZE, tofp);
+    while (fromChunkSize > 0) {
+        if (fromChunkSize > BUF_SIZE)
+            size = BUF_SIZE;
+        else
+            size = fromChunkSize;
+        fromSize = fread(fromBuf, 1, size, fromfp);
+        for (i = 0; i < size; i++) {
+            if (fromBuf[i] == 0x80) {
+                toBuf[i*2] = 0;
+                toBuf[i*2+1] = 0;
+            } else {
+                uval = (unsigned short)fromBuf[i];
+                if (uval > 0x80) {
+                    uval = (uval - 0x80) * 256;
+                    sval = (short)uval;
+                } else {
+                    uval = (0x80 - uval) * 256;
+                    sval = ((short)uval) * (-1);
+                }
+                toBuf[i*2] = sval;
+                toBuf[i*2+1] = sval;
+            }
+        }
+        toSize = fwrite(toBuf, 4, size, tofp);
+        fromChunkSize -= size;
+    }
+    fclose(tofp);
+    fclose(fromfp);
+}
\ No newline at end of file