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/
Revision 0:40a09c55e5be, committed 2015-11-07
- Comitter:
- ksekimoto
- Date:
- Sat Nov 07 12:21:19 2015 +0000
- Child:
- 1:a2bd45c3b373
- Commit message:
- The frist version
Changed in this revision
--- /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(§ors[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