MainWindow.xamlのソースについては以下のようになっています(※画面部分のソースコードの解説は本連載の趣旨から外れるので割愛します)。
<Window x:Class="SpeechRecognitionAPI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SpeechRecognitionAPI"
mc:Ignorable="d"
Title="Speech Recognition API" Height="350" Width="525">
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Name="btnRec" Width="200" Height="50" Click="btnRec_Click">
<StackPanel Orientation="Horizontal">
<Label Name="lblBtnRec" Width="35" Height="30" Content="REC" Background="Red" Foreground="White" Visibility="Collapsed"/>
<TextBlock Name="tblkBtnRec" Margin="20,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<ComboBox Name="cmbLocale" Width="200" Margin="0,20,0,0">
<ComboBoxItem Content="ja-JP" IsSelected="True" />
<ComboBoxItem Content="en-US" />
</ComboBox>
<TextBox Name="tboxResult" Width="450" Height="150" TextWrapping="Wrap" Margin="0,20,0,0" />
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.csで実際にプログラムから呼び出すところを作成します。プログラムの流れとしては非常にシンプルで、以下のようになります。
Text To Speech APIと同様、サービスが対応している言語の一覧を取得するAPIがないようなので、今回はプログラム内にリストを持つことにします(プログラムを簡便にするために、今回は英語と日本語のみとします)。
まず、今回はSpeech Recognition APIから返ってくるデータがJSON形式なので、このJSON形式で返ってくるデータを受け取るためのクラスを作成します。
メニューバーの「プロジェクト」から「クラスの追加」をクリックします。
追加するのは通常のクラスです。名前を「SpeechRecognitionResult.cs」として「追加」ボタンをクリックします。
クラスが追加されたら、以下の内容をコピーしてそのクラスにペーストしてください。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// 追加
using System.Runtime.Serialization;
namespace SpeechRecognitionAPI
{
[DataContract]
class SpeechRecognitionResult
{
[DataMember]
public string version { get; set; }
[DataMember]
public Header header { get; set; }
[DataMember]
public Result[] results { get; set; }
[DataContract]
public class Header
{
[DataMember]
public string status { get; set; }
[DataMember]
public string scenario { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string lexical { get; set; }
[DataMember]
public Properties properties { get; set; }
}
[DataContract]
public class Properties
{
[DataMember]
public string requestid { get; set; }
[DataMember]
public string HIGHCONF { get; set; }
}
[DataContract]
public class Result
{
[DataMember]
public string scenario { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string lexical { get; set; }
[DataMember]
public string confidence { get; set; }
[DataMember]
public Properties2 properties { get; set; }
}
[DataContract]
public class Properties2
{
[DataMember]
public string HIGHCONF { get; set; }
}
}
}
続いてアクセスキーを使用してTokenを取得する処理ですが、Tokenの取得については、Translator API、Text To Speech APIのときとまったく同じです。Tokenは10分間有効なので、前回取得時から10以上経過していたら再取得するよう、取得した時間を変数に取っておきます。
// ----------------------------------------------
// Tokenを取得する処理
// ----------------------------------------------
string GetAccessToken()
{
try
{
//取得したBing Speech API の Key
string subscriptionKey = "xxxxxxxxxxxxxxxxxxxxxxxx";
WebRequest request = WebRequest.Create("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
//リクエスト設定
request.Method = "POST"; // メソッドはPOST
request.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
request.ContentLength = 0;
// リクエストを投げる
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
// レスポンスを受け取る
StreamReader streamReader = new StreamReader(responseStream);
// Tokenを取得した時間を取得
tokenRefreshedTime = DateTime.Now;
// レスポンス(Token)を返す
return streamReader.ReadToEnd();
}
catch (WebException webException)
{
Stream responseStream = webException.Response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
tblkMessage.Text = streamReader.ReadToEnd();
return null;
}
catch (Exception exception)
{
tblkMessage.Text = exception.Message;
return null;
}
}
続いて、音声ファイルを渡してテキストを取得する処理です。APIのリクエストメソッドはPOSTになります。Speech Recognition APIでは、リクエストの必須パラメーターとして以下の値を含めるように記載されています。
| Name | Format | 特記事項、例、使い方 |
|---|---|---|
| Version | Digits and "." | 推奨が3.0なので、「version=3.0」と記載すればOK |
| requestid | GUID | リクエストごとにグローバルでユニークなIDを振れ、とのことなので、プログラム内でリクエストのたびにIDを取得する。例としては「requestid=b2c95ede-97eb-4c88-81e4-80f32d6aee54」という形式になっている |
| appID | GUID | 固定値とのこと。「appID = D4D52672-91D7-4C74-8AD8-42B1D98141A5」と記載すればOK |
| format | UTF-8 | 推奨形式はJSON(それ以外にどのような形式をサポートしているのかの記述がない)。「format=json」と記載すればOK |
| locale | UTF-8(IETF Language Tag) | 「Bing Speech Recognition API」のページの「Supported Locales」にある値(ja-JP、en-USなど)を指定すればOK |
| device.os | UTF-8 | このリクエストを投げるアプリケーションが載っているOSを指定するパラメーター。こうでなければならないというのはないが、「Windows OS」「Windows Phone OS」「XBOX」「Android」「iPhone OS」といった形で指定すればOK |
| scenarios | UTF-8 | 音声認識を実行するための文脈、背景、場面のパラメーター。サポートする値は「ulm」か「websearch」。いろいろ調べてはみたが、このパラメーターをそれぞれ変えることによる影響は不明 |
| instanceid | GUID | デバイスごとにグローバルでユニークなIDを振れ、とのことなので、何か適当な値を固定値で持ってもいいし、都度新しいIDを取得しても問題ないようだ。例としては「instanceid=b2c95ede-97eb-4c88-81e4-80f32d6aee54」という形式になっている |
// ----------------------------------------------
// 音声データのテキスト変換結果を取得する処理
// ----------------------------------------------
string GetSpeechRecognitionResult(string pAccessToken, string pLocale, string pWavFile)
{
try
{
string url = " https://speech.platform.bing.com/recognize";
url += "?version=3.0";
url += "&requestid=" + Guid.NewGuid().ToString();
url += "&appid=D4D52672-91D7-4C74-8AD8-42B1D98141A5";
url += "&format=json";
url += "&locale=" + pLocale;
url += "&device.os=Windows OS";
url += "&scenarios=ulm";
url += "&instanceid=" + Guid.NewGuid().ToString();
// リクエスト作成
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.ContentType = "audio/wav; samplerate=16000";
request.Headers.Add("Authorization", "Bearer " + pAccessToken);
// 音声ファイルの読み込み
FileStream fs = new FileStream(pWavFile, FileMode.Open, FileAccess.Read);
byte[] bs = new byte[fs.Length];
fs.Read(bs, 0, bs.Length);
fs.Close();
Stream writer = request.GetRequestStream();
writer.Write(bs, 0, bs.Length);
WebResponse webResponse = request.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(SpeechRecognitionResult));
SpeechRecognitionResult result = (SpeechRecognitionResult)dcjs.ReadObject(responseStream);
if(result.header.status == "error")
{
return result.header.status;
}
return result.results[0].lexical;
}
catch (WebException webException)
{
Stream responseStream = webException.Response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
return streamReader.ReadToEnd();
}
catch (Exception exception)
{
return exception.Message;
}
}
コンストラクタやボタンクリック時のイベントを含めると、最終的には「MainWindow.xaml.cs」は、こちらのようになります(※クリックしてダウンロードできます)。
ポイントとしては、録音にはmciSendStringを使用しています。また、以前は音声ファイルのサンプリングレートが16khzという制限があった記憶がありますが、2017年4月現在のドキュメントには特にサンプリングレートに関する制限は書かれていません。しかし、念のため今回のプログラムでは録音時にサンプリングレート16khzの音声ファイルを作成しています。
また、返ってくるJSONのデータのうち、音声データのテキスト化の結果が入っている値は「name」「lexical」です。基本的にnameを使えばいいと思います。
ボットにCognitive Servicesを組み込んでみる
米IBMがビッグデータ分析基盤サービスを拡充、コグニティブコンピューティングの研究成果も搭載
Google Cloud Vision APIのパブリックβ版が公開Copyright © ITmedia, Inc. All Rights Reserved.