2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
はじめに
みなさん、こんにちは。
KDDIウェブコミュニケーションズの Twilio エバンジェリストの高橋です。
今回は、Twilio を利用する上で知っておきたい DTMF 信号の扱いについて解説します。
そもそも DTMF とは
みなさんは、トーン信号とかプッシュ信号という言葉を聞いたことがあるかと思います。そう、電話機の数字キーとシャープ、アスタリスクなどを押すことで発生する「ピッ」っていう音です。
このトーン信号のことを別名 DTMF(Dual-Tone Multi-Frequency)信号と呼び、DTMF はその名の通り2つの異なる周波数を使ってトーン信号を表現する方法です。
*出典 ウィキペディア
上の表を見るとわかるように、例えば数字の「1」を表現するためには、697Hzと1209Hzの2つの周波数音を重ねて送出します。
DTMFの限界
このように、人間の耳で聞こえる周波数帯で、しかも他の音とは混在しないようなしくみで数字を伝えるという技術は、たとえばコールセンターの IVR システムなどでも用いられています。
しかし一方で、周波数に依存する方式では外部の雑音などに弱かったり、コーデック(周波数を数値に変換するしくみ)によってうまく認識ができないことがあります。
そもそも現在の電話システムの裏側は、IPベースでの通信になっているため、たとえば DTMF でそのままパケットで送信しようとすると、1つの音が複数のパケットに分割されて伝搬されます。
パケットが複数に分割された場合、ネットワークの状況によってはパケットロスやジッターが発生することで一部のパケットが届かなくなることがあります(下の図を参照)。
このケースでは、1つのDTMFの途中のパケットが欠損してしまったため、本来は1つのDTMFが2つになって聞こえてしまいます(1を2回押したことになる)。
このような状況を回避するためにはいくつか方法があります。
解決策1 ジッターバッファなどを調整することで欠損を減らす
ジッターというのは、パケットの「ゆらぎ」のことです。複数に分割されたパケットは、必ずしも同じ経路で相手側に伝搬されるわけではなく、色々なルートに別れて届くことになります。その場合、経路によっては届く時間が異なります。
音声データは早く届きすぎてもだめですし、逆に遅すぎてもだめです。これを「等時性」と呼びます。
等時性を確保するために、パケットを組み立てるときに調整が行われます。わかりやすくいうと、届いたパケットをジッターバッファと呼ばれる領域に入れて、そこで時系列に沿ってパケットを組み立て直すのです(ゆらぎ吸収とも呼ばれます)。
このときに、吸収できなかったパケットは、残念ながら欠損してしまいます。
そのため、ジッターバッファを多めに用意することで、届かないパケットを減らすことができるのです。しかしバッファを増やすと逆に遅延が発生することになります。音声通話における遅延は、聞きづらさにつながるため、あまり長くすることはできません。
解決策2 DTMF信号の長さを短くする
そもそもDTMF信号が長いとパケットロスやジッターの影響を受けやすくなるので、判定に必要な最低の長さで送り出すことで対策が可能です。
たとえば、筆者が実際に iPhone7 と iPhone11 でテストしてみたところ、iPhone7 では 300ms 程度の長さであるものが、iPhone11 では 125ms 程度の長さになって聞こえます。
どうも Apple 社は最新の iPhone では DTMF 信号の長さを故意に短くしているようです。このショートトーンを採用しているのは iPhone の比較的新しい機種(どの機種からかはわかりません)からで、Android や iPhoneの古い機種では採用されていません。これはすなわち、Android では DTMF による問題が発生しやすいということにもなります。
解決策3 RFC2833 を採用する
先程も書いたように、現在電話システムの裏側はパケット通信で行われています。そのため、DTMF による伝搬を行うよりも、IP パケットに数字自体を信号として記録して伝搬したほうが効率的です。
そこで利用される方式が RFC2833 という方式です。
RFC2833 では、トーン信号を周波数ではなくて専用のパケット仕様として定義して伝搬します。これによりパケットロスやジッターの影響は受けにくくなります(RFC2833 を採用したとしても、パケット自体は RTP により伝搬されるので影響が完全になくなるわけではありません)。
「RFC2833」と「みなし音声」
ここからは、RFC2833 と比較するために、従来の DTMF を「みなし音声」として説明します。みなし音声とは、その名の通り音声データのようにみなして数字を送ることからついた名称です。英語では、in-band DTMF と呼ばれます。
日本では、古くから使われていたみなし音声にしか対応していない機器などもあるため、電話機からはみなし音声が出ていくケースがほとんどです。ただし、Twilio のような IP ベースの電話システムでは上記の理由から RFC2833 をサポートしています(みなし音声が来た場合はパススルーするという説明もあります)。
電話機側からみなし音声が入ってきた場合に、それを RFC2833 に変換するかは機器の機能として実装されるため、はっきりとした回答は公式にはされていませんが、最近は変換されると考えるのが一般的です。
当然逆もしかりで、RFC2833 をみなし音声に変換する作業も機器に依存します。
これを確認するために、ちょっとした実験をしてみたいと思います。
実験は次の2つのケースで行います。
(A) スマートフォン -> Twilio (DialによるPSTN転送) -> スマートフォン
(B) スマートフォン -> Twilio (DialによるSIP転送) -> SIPフォン
それぞれの状態で、スマートフォンの数字キーを入力してみると、
(A)は、みなし音声として相手のスマートフォンから「ピッピッ」という音がちゃんと聞こえます。
一方(B)では、SIPフォン側にはタップ音しか聞こえません。
(B)では、Twilio と SIP フォンの間がパケット通信になるため、RFC2833 からみなし音声への逆変換がされずに、タップ音しか聞こえないのです。
本当に RFC2833 になっているのか、SIP フォン側でパケットキャプチャーを取得して確認してみました。
RFC2833 では、信号を RTP EVENT というパケットにして伝搬するように規定されています。
このパケット内容は先に記述した RFC2833 の定義にも記載がありますので、気になる方はぜひリファレンスを読み解いてください。
この結果から、どうやらちゃんと変換がされていますね。
まとめ
ということで、少なくとも現在、日本国内ではみなし音声による DTMF は内部的には RFC2833 に変換されることがわかりましたね(逆も同じです)。
裏側の仕組みをちゃんと理解しておくことで、トラブルシューティングの役にもたつはずなので、ぜひこの機会に覚えておくとよいでしょう。
では素敵な Twilio ライフを。
Twilio(トゥイリオ)とは
https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング(SMS /チャット)、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。