slanted W3C logo
Cover page images (keys)

Web と話してみませんか?
 - あなたも使える音声ブラウザ

W3C Voice Browser ワーキンググループ担当 芦村和幸 <ashimura@w3.org>

日常生活と Web

web_and_voice

Web へのアクセス方法

基本的にはキー操作

携帯電話:

パソコン/PDA:

こんなときは,どうする?

ちょっと Web サイトで調べたいことが

→でも,パソコンを持ってこなかった...

携帯電話でもアクセスできるかもしれない

→でも,携帯電話でアクセスするのは,ちょっと面倒かもしれない

たとえば,車を運転していたら?

→運転中は,携帯電話の操作をしてはいけません!

声で Web にアクセス!

手が離せなくても,電話で話すことは可能

* パソコンやPDAのような難しいキー操作なしに

* 世界中のどこにでもある普通の電話で

* 声や簡単なボタン操作だけで

Web(インターネット)にアクセスする仕組があればいい

それが「音声ブラウザ」

音声ブラウザの利用例

天気予報

時刻表

留守電

銀行振込

チケット購入

音声ブラウザって,どうやって使うの?

使い方

利用者は,サーバに電話をかけて,声とボタンで操作するだけ

アプリケーション

銀行振込などの具体的なアプリケーションは,別途,アプリケーション開発者が作成

音声ブラウザ

音声ブラウザは,別途,ブラウザの開発ベンダが提供

簡単なデモ

[電話でビデオ録画]

日帰り出張で東京へ

あっ,ビデオのタイマをかけてくるのを忘れた.

これから帰ると間に合わない!!!

そんな時でも大丈夫 ;-)

W3C によるインタフェース仕様標準化

さまざまな機能を組合せ
簡単かつ確実にアプリケーション開発

* 音声端末の操作方法 (人とのインタフェース)

* 端末とブラウザとのインタフェース

* ブラウザとアプリケーションとのインタフェース

web_and_voice

音声インタフェースフレームワーク

音声ブラウザ実現に必要な
マークアップ言語仕様集

Voice Browser architecture and standards

音声インタフェースフレームワークの構成要素

VoiceXML/CCXML/SCXML : 対話制御

SISR/SRGS : 音声認識

SSML : 音声合成

PLS : 合成と認識のための辞書

まとめ

日常生活と深く関わる Web

音声による Web アクセス

W3C が進めるインタフェース仕様の標準化

音声インタフェースフレームワーク詳細

http://www.w3.org/TR/voice-intro/

Speech Interface Framework

マークアップ言語の例1:
 VoiceXML のみを用いた単純な制御

VoiceXML: main.vxml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vxml PUBLIC "-//Nuance/DTD VoiceXML 1.0//EN" "http://voicexml.nuance.com/dtd/nuancevoicexml-1-2.dtd" >
<vxml>

<form id="when">

<!-- 曜日 -->
<field name="date">
<grammar src="Date.grammar#Date"/>
<prompt>何曜日ですか?</prompt>
<filled namelist="date">
<if cond="date=='getsuyoo'">
<prompt>月曜日ですね。</prompt>
</if>
<if cond="date=='kayoo'">
<prompt>火曜日ですね。</prompt>
</if>
<if cond="date=='suiyoo'">
<prompt>水曜日ですね。</prompt>
</if>
<if cond="date=='mokuyoo'">
<prompt>木曜日ですね。</prompt>
</if>
<if cond="date=='kinnyoo'">
<prompt>金曜日ですね。</prompt>
</if>
<if cond="date=='doyoo'">
<prompt>土曜日ですね。</prompt>
</if>
<if cond="date=='nichiyoo'">
<prompt>日曜日ですね。</prompt>
</if>
</filled>
</field>

<!-- 開始時刻 -->
<field name="st">
<grammar src="Time.grammar#Time"/>
<prompt>何時からですか?</prompt>
<filled namelist="st">
<if cond="st=='ichiji'">
<prompt>一時からですね。</prompt>
</if>
<if cond="st=='niji'">
<prompt>二時からですね。</prompt>
</if>
<if cond="st=='sannji'">
<prompt>三時からですね。</prompt>
</if>
<if cond="st=='yoji'">
<prompt>四時からですね。</prompt>
</if>
<if cond="st=='goji'">
<prompt>五時からですね。</prompt>
</if>
<if cond="st=='rokuji'">
<prompt>六時からですね。</prompt>
</if>
<if cond="st=='shichiji'">
<prompt>七時からですね。</prompt>
</if>
<if cond="st=='hachiji'">
<prompt>八時からですね。</prompt>
</if>
<if cond="st=='kuji'">
<prompt>九時からですね。</prompt>
</if>
<if cond="st=='juuji'">
<prompt>十時からですね。</prompt>
</if>
<if cond="st=='juuichiji'">
<prompt>十一時からですね。</prompt>
</if>
<if cond="st=='juuniji'">
<prompt>十二時からですね。</prompt>
</if>
</filled>
</field>

<!-- 終了時刻 -->
<field name="et">
<grammar src="Time.grammar#Time"/>
<prompt>何時までですか?</prompt>
<filled namelist="et">
<if cond="et=='ichiji'">
<prompt>一時までですね。</prompt>
</if>
<if cond="et=='niji'">
<prompt>二時までですね。</prompt>
</if>
<if cond="et=='sannji'">
<prompt>三時までですね。</prompt>
</if>
<if cond="et=='yoji'">
<prompt>四時までですね。</prompt>
</if>
<if cond="et=='goji'">
<prompt>五時までですね。</prompt>
</if>
<if cond="et=='rokuji'">
<prompt>六時までですね。</prompt>
</if>
<if cond="et=='shichiji'">
<prompt>七時までですね。</prompt>
</if>
<if cond="et=='hachiji'">
<prompt>八時までですね。</prompt>
</if>
<if cond="et=='kuji'">
<prompt>九時までですね。</prompt>
</if>
<if cond="et=='juuji'">
<prompt>十時までですね。</prompt>
</if>
<if cond="et=='juuichiji'">
<prompt>十一時までですね。</prompt>
</if>
<if cond="et=='juuniji'">
<prompt>十二時までですね。</prompt>
</if>
</filled>
</field>

<!-- チャンネル -->
<field name="channel">
<grammar src="Channel.grammar#Channel"/>
<prompt>何チャンネルですか?</prompt>
<filled namelist="channel">
<if cond="channel=='ichi'">
<prompt>一チャンネルですね。</prompt>
</if>
<if cond="channel=='ni'">
<prompt>二チャンネルですね。</prompt>
</if>
<if cond="channel=='sann'">
<prompt>三チャンネルですね。</prompt>
</if>
<if cond="channel=='yonn'">
<prompt>四チャンネルですね。</prompt>
</if>
<if cond="channel=='go'">
<prompt>五チャンネルですね。</prompt>
</if>
<if cond="channel=='roku'">
<prompt>六チャンネルですね。</prompt>
</if>
<if cond="channel=='nana'">
<prompt>七チャンネルですね。</prompt>
</if>
<if cond="channel=='hachi'">
<prompt>八チャンネルですね。</prompt>
</if>
<if cond="channel=='kyuu'">
<prompt>九チャンネルですね。</prompt>
</if>
<if cond="channel=='juu'">
<prompt>十チャンネルですね。</prompt>
</if>
<if cond="channel=='juuichi'">
<prompt>十一チャンネルですね。</prompt>
</if>
<if cond="channel=='juuni'">
<prompt>十二チャンネルですね。</prompt>
</if>
</filled>
</field>

<prompt>では録画します。</prompt>

<catch event="nomatch noinput">
<prompt>すいません。聞き取ることができませんでした。</prompt>
<goto next="#when"/>
</catch>
</form>

</vxml>

文法ファイル: Date.grammar

Date
[
[げつよう げつ げつようび] {<date "getsuyoo">}
[かよう か かようび] {<date "kayoo">}
[すいよう すい すいようび] {<date "suiyoo">}
[もくよう もく もくようび] {<date "mokuyoo">}
[きんよう きん きんようび] {<date "kinnyoo">}
[どよう ど どようび] {<date "doyoo">}
[にちよう にち にちようび] {<date "nichiyoo">}
]

文法ファイル: Time.grammar

Time
[
[いちじ いち] {<time "ichiji">}
[にじ に] {<time "ni">}
[さんじ さん] {<time "sannji">}
[よじ よん] {<time "yoji">}
[ごじ ご] {<time "goji">}
[ろくじ ろく] {<time "rokuji">}
[しちじ しち なな] {<time "shichiji">}
[はちじ はち] {<time "hachiji">}
[くじ きゅう] {<time "kuji">}
[じゅうじ じゅう] {<time "juuji">}
[じゅういちじ じゅういち] {<time "juuichiji">}
[じゅうにじ じゅうに] {<time "juuniji">}
]

文法ファイル: Channel.grammar

Channel
[
[いっちゃん いち] {<channel "ichi">}
[にちゃん に] {<channel "ni">}
[さんちゃん さん] {<channel "sann">}
[よんちゃん よん し] {<channel "yonn">}
[ごちゃん ご] {<channel "go">}
[ろくちゃん ろく] {<channel "roku">}
[ななちゃん なな しち] {<channel "nana">}
[はっちゃん はち] {<channel "hachi">}
[きゅうちゃん きゅう] {<channel "kyuu">}
[じゅっちゃん じゅう] {<channel "juu">}
[じゅういっちゃん じゅういち] {<channel "juuichi">}
[じゅうにちゃん じゅうに] {<channel "juuni">}
]

マークアップ言語の例2:
 SCXML を用いた状態遷移の例

<?xml version="1.0" encoding="us-ascii"?>

<!-- A wrapper state that contains all other states in this file
- it represents the complete state machine -->
<scxml xmlns="http://www.w3.org/2005/07/scxml"
       version="1.0"
       initalstate="Main">  
  <state id="Main">
    <!-- its initial state is Test1 -->
    <initial>
      <transition>
        <target next="Test1"/>
      </transition>
    </initial>
   ...
   ...
   ...
    <!-- 
         - This state shows invocation of external component
         - We will use CCXML + VoiceXML actions as an example 
         - as it is a good smoke test to show how it all 
         - fits together. 
         - Note: Odds are in a real app you would 
         - split this over several states but we 
         - are trying to keep it simple here. 
    -->
    <state id="Test6"
           xmlns:ccxml="http://www.w3.org/2002/09/ccxml"
           xmlns:v3="http://www.w3.org/2005/07/vxml3">
      <onentry>
        <!--
            - Use <send> to run a createcall using the 
            - CCXML component / Event I/O Processor
        -->
        <var name="dest" expr="'tel:+18315552020'"/>

        <send targettype="ccxml" event="ccxml:createcall" namelist="dest"/>
      </onentry>
      <transition event="ccxml:connection.connected" name="evt">      
        <!--
            - Here we use example V3 
            - Custom Action Elements instead of send . 
        -->
        <v3:form id="HelloWorld">
          <v3:block><v3:prompt>Hello World!</v3:prompt></v3:block>          
        </v3:form>

      </transition>
      <!--
          - Here we are using the low level <send> 
          - element to run a v3 form. Note that the event "v3:HelloWorld.done" 
          is assumed either to be set/sent explicitly by the v3:form code or 
          implicitly by some process outside of the v3:form
      -->
      <transition event="v3:HelloWorld.done" name="evt">
        <var name="src" expr="'helloworld2.vxml'"/>
        <var name="id" expr="'HelloWorld'"/>

        <send targettype="v3" event="v3:formstart" namelist="src id"/>
      </transition>
      <transition event="v3:HelloWorld2.done" name="evt">
        <ccxml:disconnect connectionid="evt.connectionid"/>      
      </transition>
      <transition event="ccxml:connection.disconnected">

        <!--
            - Here we are using the <exit/> shorthand to 
            - move ourself to a final state.
            - In this example you could do <target next="Done"/>
            - and get the same result.
        -->
        <exit/>
      </transition>
      <!-- Transitions to handle events generated by the component
           - component invoked successfully. this transition has no target 
           - so Test6 is not exited.
           - We are just going to log tha we were able to send an event. -->

      <transition event="send.successful">
        <log expr="'Event was able to be sent'"/>
      </transition>
      <!--
          - If we get an error event we move to the Done state that 
          - is a final state. 
      -->
      <transition event="error.send">
        <log expr="'Sending to and External component failed'"/>

        <target next="Done"/>
      </transition>
      <onexit>
        <log expr="'Finished with external component'"/>
      </onexit>
    </state>

    <!-- This final state is an immediate child of Main
         -  when we get here, Main.done is generated. -->
    <state id="Done" final="true"/>
    <!-- End of Main > -->
  </state>
</scxml>