DTMF
- Dual-Tone Multi-Frequency -
DTMF
- Dual-Tone Multi-Frequency -
EZ-‐‑‒NET  熊⾕谷友宏 @EasyStyleGK
http://program.station.ez-‐‑‒net.jp/
〜DTMFと自作アプリの軌跡〜〜DTMFと自作アプリの軌跡〜
⾃自⼰己紹介
@EasyStyleGK
EZ-‐‑‒NET  IP  Phone ⾳音で再配達ゴッド
⾳音で再配達 ⾳音でダイヤル いつもの電卓
for  iPad
いつもの電卓
for  iPhone
iOS  アプリ
制作中
iOS  アプリ
制作中
EZ-‐‑‒NET  熊⾕谷友宏
http://program.station.ez-‐‑‒net.jp/
これらのアプリにまつわるお話
EZ-‐‑‒NET  IP  Phone ⾳音で再配達ゴッド
⾳音で再配達 ⾳音でダイヤル いつもの電卓
for  iPad
いつもの電卓
for  iPhone
DTMFDTMF
テーマはテーマは
はじまり
1. DTMF  との出逢い
2. アイデアとの出逢い
3. そして神アプリへ
1. DTMF  との出逢い
2. アイデアとの出逢い
3. そして神アプリへ
題⽬目題⽬目
第1章
DTMF との出逢いDTMF との出逢い
電話アプリを制作していたときのこと
• 通話中の番号ボタンが必要になる
• 番号ボタンといえば ピ・ポ・パ
• ピ・ポ・パ といえば DTMF
• 通話中の番号ボタンが必要になる
• 番号ボタンといえば ピ・ポ・パ
• ピ・ポ・パ といえば DTMF
何気なく使っている DTMF
そういえば
どうやって送ってるの?
そういえば
どうやって送ってるの?
⾳音としてそのまま送信⾳音としてそのまま送信
DTMF  ってどんな⾳音?
1. ふたつの正弦波で構成される⾳音
2. 正弦波の組み合わせによって
0 ~∼  9,  #,  *,  A ~∼  D と呼ばれる
3. 秒間 8  数字以上の転送が可能
1. ふたつの正弦波で構成される⾳音
2. 正弦波の組み合わせによって
0 ~∼  9,  #,  *,  A ~∼  D と呼ばれる
3. 秒間 8  数字以上の転送が可能
特徴特徴
DTMF  ってどんな⾳音?
1. ひとつの⾳音の⻑⾧長さは
最低 50ms  以上(信号送出時間)
2. ⾳音と⾳音の間は間隔を開ける
最低 30ms  以上(ミニマムポーズ)
3. 信号送出時間とミニマムポーズで
合計 120ms  以上の時間を取ること
1. ひとつの⾳音の⻑⾧長さは
最低 50ms  以上(信号送出時間)
2. ⾳音と⾳音の間は間隔を開ける
最低 30ms  以上(ミニマムポーズ)
3. 信号送出時間とミニマムポーズで
合計 120ms  以上の時間を取ること
送信のルール送信のルール
DTMF  ってどんな⾳音?
正弦波の組み合わせ正弦波の組み合わせ
1209 1477 1633
697
852
941
1336
770低
群
㎐
⾼高群 ㎐
DTMF  ⾳音を作る
y=sinθ  で表現される波形y=sinθ  で表現される波形
正弦波の基本形正弦波の基本形
1周期は 2π1周期は 2π
範囲は -1 から +1範囲は -1 から +1
θθ
yy
DTMF  ってどんな⾳音?
θ  はラジアン単位の⾓角度度θ  はラジアン単位の⾓角度度
11
11
11
1. 弧の長さで角度を表現する方法
2. 半径 1  の円で、弧の⻑⾧長さが
1  になるときの⾓角度度が 1  ラジアン
3. 半円の弧の⻑⾧長さを π と定義する
• 180° は π ラジアン
• 半分の 90 ならπ/2
1. 弧の長さで角度を表現する方法
2. 半径 1  の円で、弧の⻑⾧長さが
1  になるときの⾓角度度が 1  ラジアン
3. 半円の弧の⻑⾧長さを π と定義する
• 180° は π ラジアン
• 半分の 90 ならπ/2
DTMF  ってどんな⾳音?
1. 半径が1の半円の弧の⻑⾧長さ
2. 半径倍すればその円の弧の⻑⾧長さ
3. π= 3.14159 26535 89793 …
1. 半径が1の半円の弧の⻑⾧長さ
2. 半径倍すればその円の弧の⻑⾧長さ
3. π= 3.14159 26535 89793 …
πは円周率率率と呼ぶπは円周率率率と呼ぶ
ππ
11
DTMF  ってどんな⾳音?
1. 半径が 1  の円における
引数の⾓角度度が作る弧の y  座標
• θ=0π(0 ) は y=0
• θ=π/2 (90 ) のときは y=1
2. 半径 1 の単位円なので
y は -1 から 1 になる
3. θ=2π(360 )で
1周して元に戻る(2π周期)
1. 半径が 1  の円における
引数の⾓角度度が作る弧の y  座標
• θ=0π(0 ) は y=0
• θ=π/2 (90 ) のときは y=1
2. 半径 1 の単位円なので
y は -1 から 1 になる
3. θ=2π(360 )で
1周して元に戻る(2π周期)
sin 関数sin 関数
θθ
11
yy
DTMF  ⾳音を作る
周波数 1Hz  とは周波数 1Hz  とは
1周期は 2π1周期は 2π
範囲は -1 から +1範囲は -1 から +1
1  秒間に 1  周期が現れる波形1  秒間に 1  周期が現れる波形
1秒1秒
θθ
yy
DTMF  ⾳音を作る
周波数が 770Hz  なら周波数が 770Hz  なら
1周期は 2π1周期は 2π
範囲は -1 から +1範囲は -1 から +1
1  秒間に 770  周期の波形
つまり 1/770  秒で 1  周期の波形
1  秒間に 770  周期の波形
つまり 1/770  秒で 1  周期の波形
1/770  秒1/770  秒
θθ
yy
DTMF  ⾳音を作る
y=sin(770×θ)  y=sin(770×θ)  
770Hz  の正弦波を式で表すと770Hz  の正弦波を式で表すと
1周期は 2π/7701周期は 2π/770
1/770  秒1/770  秒
θθ
yy
DTMF  ⾳音を作る
DTMF  の ʻ‘5ʼ’  を鳴らしたいならDTMF  の ʻ‘5ʼ’  を鳴らしたいなら
770Hz と 1336Hz の
正弦波を合成する
770Hz と 1336Hz の
正弦波を合成する
何気なく使っている DTMF
正弦波って
どうやって合成するの?
正弦波って
どうやって合成するの?
それぞれを計算して
普通に⾜足し合わせるだけ
それぞれを計算して
普通に⾜足し合わせるだけ
DTMF  ⾳音を作る
つまりつまり
範囲は最大でも
-2 から +2
範囲は最大でも
-2 から +2
y  =  sin(770×θ)  +  sin(1336×θ)y  =  sin(770×θ)  +  sin(1336×θ)
θθ
yy
DTMF  ⾳音を作る
このようにして
DTMF  波形は作られている
このようにして
DTMF  波形は作られている
DTMF  ⾳音の再⽣生⽅方法
DTMF  波形の
再⽣生⽅方法
DTMF  波形の
再⽣生⽅方法
DTMF  ⾳音の再⽣生⽅方法
1. DTMF  波形をプログラムで
計算して⽣生成する⽅方法
2. サウンドファイルを
⽤用意して再⽣生する⽅方法
1. DTMF  波形をプログラムで
計算して⽣生成する⽅方法
2. サウンドファイルを
⽤用意して再⽣生する⽅方法
DTMF  波形を再⽣生する⽅方法としてはDTMF  波形を再⽣生する⽅方法としては
DTMF  ⾳音の再⽣生⽅方法
DTMF  波形をプログラムで
計算して⽣生成する⽅方法
DTMF  波形をプログラムで
計算して⽣生成する⽅方法
1.1.
DTMF  波形を⽣生成する⽅方法
Remote  IO  を使って
波形データを⽣生成する
Remote  IO  を使って
波形データを⽣生成する
DTMF  波形を⽣生成する⽅方法
Remote  IO  について
詳しく知りたい⼈人には
この書籍が超お勧め!
Remote  IO  について
詳しく知りたい⼈人には
この書籍が超お勧め!
詳細は割愛詳細は割愛
絶版らしいのが悲しい絶版らしいのが悲しい
DTMF  波形を⽣生成する⽅方法
⼤大変お世話になっております。⼤大変お世話になっております。
超お勧めの Web  サイト超お勧めの Web  サイト
Objective-‐‑‒Audio
Mac  と iPhone  でオーディオプログラミング
Objective-‐‑‒Audio
Mac  と iPhone  でオーディオプログラミング
http://objective-audio.jp/http://objective-audio.jp/
DTMF  波形を⽣生成する⽅方法
概要としては概要としては
1. Audio Unit を初期化する
2. コールバック関数を登録する
3. Audio Unit を実行する
4. コールバック関数が呼ばれたら
波形データを計算してバッファに書
く
1. Audio Unit を初期化する
2. コールバック関数を登録する
3. Audio Unit を実行する
4. コールバック関数が呼ばれたら
波形データを計算してバッファに書
く
DTMF  波形を⽣生成する⽅方法
波形データの書き込み波形データの書き込み
1. バッファに何秒目から何秒間のデータを
書き込むかはプログラマが管理する
2. バッファが何秒間のデータかは
サンプリングレートで判断できる
3. サンプリングレートとは
何個のデータで 1 秒の音を作るかを示す
1. バッファに何秒目から何秒間のデータを
書き込むかはプログラマが管理する
2. バッファが何秒間のデータかは
サンプリングレートで判断できる
3. サンプリングレートとは
何個のデータで 1 秒の音を作るかを示す
DTMF  波形を⽣生成する⽅方法
Remote  IO  って
ちょっと難しい
Remote  IO  って
ちょっと難しい
DTMF  波形を⽣生成する⽅方法
Remote  IO  の利利点Remote  IO  の利利点
1. 波形データを直接扱える
2. タイミングの細やかな調整が可能
3. 音声フォーマットの変換も可能
1. 波形データを直接扱える
2. タイミングの細やかな調整が可能
3. 音声フォーマットの変換も可能
⾳音声データをネットワーク経由で
送信したいときにも威⼒力力を発揮する
⾳音声データをネットワーク経由で
送信したいときにも威⼒力力を発揮する
DTMF  ⾳音の再⽣生⽅方法2
サウンドファイルを
⽤用意して再⽣生する⽅方法
サウンドファイルを
⽤用意して再⽣生する⽅方法
2.2.
サウンドファイルで再⽣生する⽅方法
DTMF  サウンドファイルの
⽤用意の仕⽅方としては…
DTMF  サウンドファイルの
⽤用意の仕⽅方としては…
1. サウンドエディタを使って生成する
2. インターネットでダウンロードする
1. サウンドエディタを使って生成する
2. インターネットでダウンロードする
サウンドファイルで再⽣生する⽅方法
0  〜~ 9,  *,  # だけで良良ければ0  〜~ 9,  *,  # だけで良良ければ
サウンドファイルが
iPhone  内に⽤用意されている
サウンドファイルが
iPhone  内に⽤用意されている
サウンドファイルで再⽣生する⽅方法
/System/Library/Audio/UISounds/System/Library/Audio/UISounds
• dtmf-0.caf
• dtmf-1.caf
• dtmf-2.caf
• dtmf-3.caf
• dtmf-4.caf
• dtmf-5.caf
• dtmf-0.caf
• dtmf-1.caf
• dtmf-2.caf
• dtmf-3.caf
• dtmf-4.caf
• dtmf-5.caf
• dtmf-6.caf
• dtmf-7.caf
• dtmf-8.caf
• dtmf-9.caf
• dtmf-pound.caf
• dtmf-star.caf
• dtmf-6.caf
• dtmf-7.caf
• dtmf-8.caf
• dtmf-9.caf
• dtmf-pound.caf
• dtmf-star.caf
サウンドファイルで再⽣生する⽅方法
System  Sound  Services
を使って再⽣生する
System  Sound  Services
を使って再⽣生する
サウンドファイルはサウンドファイルは
サウンドファイルで再⽣生する⽅方法
NSString* path = @"/System/Library/
Audio/UISounds/dtmf-1.caf"];
NSURL* url = [NSURL
fileURLWithPath:path];
NSString* path = @"/System/Library/
Audio/UISounds/dtmf-1.caf"];
NSURL* url = [NSURL
fileURLWithPath:path];
1.AudioToolbox.framework を組み込む1.AudioToolbox.framework を組み込む
2.DTMF  ファイルのパスを取得する2.DTMF  ファイルのパスを取得する
#import <AudioToolbox/AudioServices.h>#import <AudioToolbox/AudioServices.h>
サウンドファイルで再⽣生する⽅方法
void soundCompletion(SystemSoundID sound,
void* clientData)
{
AudioServicesDisposeSystemSoundID(
sound);
}
void soundCompletion(SystemSoundID sound,
void* clientData)
{
AudioServicesDisposeSystemSoundID(
sound);
}
3.再⽣生終了了時にサウンドのリリース処理理を
実⾏行行する関数を⽤用意する
3.再⽣生終了了時にサウンドのリリース処理理を
実⾏行行する関数を⽤用意する
サウンドファイルで再⽣生する⽅方法
SystemSoundID sound;
AudioServicesCreateSystemSoundID(
(__bridge CFURLRef)url, &sound);
SystemSoundID sound;
AudioServicesCreateSystemSoundID(
(__bridge CFURLRef)url, &sound);
4.URL  からシステムサウンドを⽣生成する4.URL  からシステムサウンドを⽣生成する
5.再⽣生終了了時に実⾏行行する関数を割り当てる5.再⽣生終了了時に実⾏行行する関数を割り当てる
AudioServicesAddSystemSoundCompletio
n(sound, NULL, NULL, soundCompletion,
NULL);
AudioServicesAddSystemSoundCompletio
n(sound, NULL, NULL, soundCompletion,
NULL);
サウンドファイルで再⽣生する⽅方法
AudioServicesPlaySystemSound(sound);AudioServicesPlaySystemSound(sound);
6.サウンドを再⽣生する6.サウンドを再⽣生する
DTMF  を再⽣生する
このような知識識を使って
DTMF  を再⽣生する
このような知識識を使って
DTMF  を再⽣生する
DTMF  を鳴らすアプリを作ってみた
• 電話アプリに組み込む前に
⾳音だけ鳴らすテストアプリを作成
• DTMF 記号を押すとその⾳音がなる
• 信号送出時間と
ミニマムポーズを調整可能
• 電話アプリに組み込む前に
⾳音だけ鳴らすテストアプリを作成
• DTMF 記号を押すとその⾳音がなる
• 信号送出時間と
ミニマムポーズを調整可能
DTMF  活⽤用例例
そういえば!そういえば!
DTMF  活⽤用例例
どこかの探偵アニメで
DTMF を発声して電話をかける
エピソードがありました
どこかの探偵アニメで
DTMF を発声して電話をかける
エピソードがありました
DTMF  活⽤用例例
⾳音の信号だから
実現可能
⾳音の信号だから
実現可能
DTMF  活⽤用例例
iPhone  の電話帳を使って
固定電話で発信できそう
iPhone  の電話帳を使って
固定電話で発信できそう
DTMF  を鳴らすアプリを改良良してみた
• 電話帳から番号を選択可能にした
• 販売したら買う⼈人もいるかも?
➡ テストアプリがお⼩小遣いになった
• 電話帳から番号を選択可能にした
• 販売したら買う⼈人もいるかも?
➡ テストアプリがお⼩小遣いになった
テストアプリの機能強化テストアプリの機能強化
DTMF  活⽤用例例
DTMF  Dialler  が
完成しました。
DTMF  Dialler  が
完成しました。
iPhone  の電話帳を使って
固定電話で電話がかけられます
iPhone  の電話帳を使って
固定電話で電話がかけられます
フィードバック
そんなある⽇日、
外国の⽅方からのフィードバックが
そんなある⽇日、
外国の⽅方からのフィードバックが
アイデアは良良いけど
pause が使えないぜ!
アイデアは良良いけど
pause が使えないぜ!
オレは連絡先の番号に
pause を使ってるのさ。
オレは連絡先の番号に
pause を使ってるのさ。
※  意訳※  意訳
DTMF  の付加価値
pause … (´́・ω・`)?pause … (´́・ω・`)?
なにそれなにそれ
RFC  3601
Dial  Sequences  and  GSTN  /  E.164  Address
【pause】【pause】
• ⼀一時停⽌止を表す記号
• 記号は “p”  で表記する
• 通常は 1  秒間の休みを取る
• ⼀一時停⽌止を表す記号
• 記号は “p”  で表記する
• 通常は 1  秒間の休みを取る
⼀一般的には “ , ”  が使われる…?⼀一般的には “ , ”  が使われる…?
RFC  3601
Dial  Sequences  and  GSTN  /  E.164  Address
【tonewait】【tonewait】
• こちらも⼀一時停⽌止を表す記号
• 記号は “w”  で表記する
• 次に進む段階が来るまで待つ
• こちらも⼀一時停⽌止を表す記号
• 記号は “w”  で表記する
• 次に進む段階が来るまで待つ
⼀一般的には “ ;; ”  が使われる…?⼀一般的には “ ;; ”  が使われる…?
公開は宝物
公開するって
勉強になりますね
公開するって
勉強になりますね
第2章
アイデアとの出逢いアイデアとの出逢い
アイデアとの出逢い
第3回 iphone_̲dev_̲jp
東京 iPhone/Mac  懇親会
第3回 iphone_̲dev_̲jp
東京 iPhone/Mac  懇親会
あれはたしかあれはたしか
での出来事での出来事
神がかったアイデア光臨臨
これで再配達の
申し込みがしたい!
これで再配達の
申し込みがしたい!
これこそまさに
技術を出発点にしない発想
これこそまさに
技術を出発点にしない発想
再配達アプリに緊急着⼿手
翌⽇日さっそく
再配達アプリ制作に着⼿手
翌⽇日さっそく
再配達アプリ制作に着⼿手
感銘を受けて感銘を受けて
再配達アプリ完成
「⾳音で再配達」が
完成しました。
「⾳音で再配達」が
完成しました。
再配達の伝票がトーン⾳音になるので
それを固定電話に聞かせて⼿手配完了了
再配達の伝票がトーン⾳音になるので
それを固定電話に聞かせて⼿手配完了了
再配達アプリ完成
iPod  touch  を愛⽤用の さんには
使ってもらえないことが判明
iPod  touch  を愛⽤用の さんには
使ってもらえないことが判明
iPhone  と iPod  touch  では
スピーカーの⾳音が少し違うようで…
iPhone  と iPod  touch  では
スピーカーの⾳音が少し違うようで…
しかしまさかのしかしまさかの
再配達アプリ完成
外部スピーカーを繋げば
使えたりします
外部スピーカーを繋げば
使えたりします
iPod  touch  でもiPod  touch  でも
たとえば iHome  iHM63  とかたとえば iHome  iHM63  とか
第3章
そして神アプリへそして神アプリへ
再配達アプリもおかげさまで
• 週刊アスキー PLUS  に
掲載されました
• そしておかげさまで
外からの声が届いて参りました
• 週刊アスキー PLUS  に
掲載されました
• そしておかげさまで
外からの声が届いて参りました
何気ないご意⾒見見
iPhone  のみで
操作が完結できたら
神アプリじゃない?
iPhone  のみで
操作が完結できたら
神アプリじゃない?
気になるご意⾒見見
神アプリ…ですと!?神アプリ…ですと!?
でも気になるご意⾒見見
さすがにそれは無理理でしょうさすがにそれは無理理でしょう
それでも気になるご意⾒見見
それがもし
実現できるとしたら?
それがもし
実現できるとしたら?
こういうときこそ逆転の発想こういうときこそ逆転の発想
…って考えると良良いって
どこかで聞いた事がある気がする
…って考えると良良いって
どこかで聞いた事がある気がする
Think different.
今こそ…
実現性の模索索1
iPhone  の電話帳に
pause  を⼊入れて使ってるよ!
iPhone  の電話帳に
pause  を⼊入れて使ってるよ!
そういえば
DTMF  Dialler  のフィードバックで
そういえば
DTMF  Dialler  のフィードバックで
とおっしゃる⼈人が居ましたねとおっしゃる⼈人が居ましたね
実現性の模索索2
pause といえば
DTMF
pause といえば
DTMF
実現性の模索索3
DTMF って
そもそも電話の仕様でしたね…
DTMF って
そもそも電話の仕様でしたね…
実現性の模索索4
iPhone  って
電話でしたよね
iPhone  って
電話でしたよね
わかったぞ…!
全ての謎が
⼀一本の線で繋がった !!
全ての謎が
⼀一本の線で繋がった !!
iPhone  の電話でも
普通に DTMF が使えるはず!
iPhone  の電話でも
普通に DTMF が使えるはず!
使えました使えました
iPhone  で DTMF  を使う
NSURL* tel = [NSURL urlWithString:
@"tel:05037869625,,,,1111”];
[[UIApplication sharedApplication]
openURL:tel];
NSURL* tel = [NSURL urlWithString:
@"tel:05037869625,,,,1111”];
[[UIApplication sharedApplication]
openURL:tel];
tel: スキームを使って
番号と⼀一緒に “  , ”  や “  ;; ”  を使うだけ
tel: スキームを使って
番号と⼀一緒に “  , ”  や “  ;; ”  を使うだけ
iPhone  に DTMF  を送信するiPhone  に DTMF  を送信する
iPhone  で DTMF  を使う
1. iPhone  の pause  は 3  秒間の待ち
2. “*”  と “#”  は、それぞれ
“%2a”  と “%23”  に置き換えて使う
1. iPhone  の pause  は 3  秒間の待ち
2. “*”  と “#”  は、それぞれ
“%2a”  と “%23”  に置き換えて使う
tel:  スキーム使⽤用時の留留意点tel:  スキーム使⽤用時の留留意点
iPhone  で DTMF  を使う
重要な制約重要な制約
tel:  を呼び出すと
制御が電話アプリに遷る
tel:  を呼び出すと
制御が電話アプリに遷る
1度度だけの呼び出しで
DTMF  を遂⾏行行させる必要がある
1度度だけの呼び出しで
DTMF  を遂⾏行行させる必要がある
こうして…こうして…
神アプリが
完成しました
神アプリが
完成しました
神アプリ完成
神アプリなので…
「⾳音で再配達ゴッド」
神アプリなので…
「⾳音で再配達ゴッド」
再配達の伝票を DTMF  にして
必要な⼿手続きを⾃自動化します
再配達の伝票を DTMF  にして
必要な⼿手続きを⾃自動化します
まとめまとめ
まとめ
DTMF  とはDTMF  とは
1. DTMF  は電話の仕様
2. ふたつの正弦波の合成⾳音
3. pause  と tonewait  がある
4. iPhone  の電話でも使⽤用可能
1. DTMF  は電話の仕様
2. ふたつの正弦波の合成⾳音
3. pause  と tonewait  がある
4. iPhone  の電話でも使⽤用可能
まとめ
制約としては制約としては
1. tel:  を呼び出したら
アプリには帰って来れない
2. tel:  を使わないなら
電話⼝口に⾳音を聞かせる必要がある
1. tel:  を呼び出したら
アプリには帰って来れない
2. tel:  を使わないなら
電話⼝口に⾳音を聞かせる必要がある
iPhone  のヘッドフォン端⼦子で外部と連携できれば
制約もまた違ってくるかもしれません
iPhone  のヘッドフォン端⼦子で外部と連携できれば
制約もまた違ってくるかもしれません
まとめ
電話の⽂文化としては
広く普及している技術ではあるので
電話の⽂文化としては
広く普及している技術ではあるので
条件が揃えば新しい何かに
応⽤用できるかもしれません
条件が揃えば新しい何かに
応⽤用できるかもしれません
まとめ
できないかも
知れないですけど
できないかも
知れないですけど
できるかは神のみぞ知るできるかは神のみぞ知る

DTMF — DTMF と自作アプリの軌跡 #yidev