[iOS] Core AnimationのCAMediaTimingFunctionでRobert Pennerのイージングを近似

2012/12/27

こんにちは。きんくまです。

Core AnimationのCABasicAnimationのイージングはAppleが用意したデフォルトの値がいくつかあります。
kCAMediaTimingFunctionLinearとかkCAMediaTimingFunctionEaseInとか。

それでその5つで指定するのも良いんですが、この間リファレンスを見ていたところ、
オリジナルのベジェカーブでもOKだということを見つけました。
– initWithControlPoints::::のところ。

>> CAMediaTimingFunction Class Reference

そうかそうかと。以前にもCSS3のTransitionのライブラリを作ったときにすでにベジェをトレースして4点とったものがあったので、こいつを使えば簡単そうということでやってみました。

ソースコードとサンプルコードはgithubにアップしてみました。

>> KinkumaDesign/CustomMediaTimingFunction · GitHub

デモの動画です。

使い方は
1. KKCustomMediaTimingFunction.hとKKCustomMediaTimingFunction.mをプロジェクトに加える
2. #import “KKCustomMediaTimingFunction.h” とヘッダファイルを加える
3. timingFunctionにこんな感じで指定すればOKです。

    [CATransaction begin];
    CABasicAnimation *basicAnimation = [CABasicAnimation animation];
    basicAnimation.duration = 1.0;

    //こんな感じ
    basicAnimation.timingFunction = [[KKCustomMediaTimingFunction alloc] initWithEasingCurve:KKCMTFEasingCurveEaseInOutExpo];
    
    basicAnimation.keyPath = @"position";
    basicAnimation.removedOnCompletion = NO;
    basicAnimation.fillMode = kCAFillModeForwards;
    basicAnimation.fromValue = [NSValue valueWithCGPoint:_sampleLayer.position];
    basicAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(320 - 50, 0)];
    [_sampleLayer addAnimation:basicAnimation forKey:nil];
    [CATransaction commit];

指定できるカーブは以下のものです。
カーブの曲線のイメージはActionScript3のライブラリTweenerのカーブを見るのがわかりやすいです。
>> Tweener Transition Types

typedef enum : NSUInteger{
    KKCMTFEasingCurveLenear =            1 << 0,
    
    KKCMTFEasingCurveEaseInSine =        1 << 1,
    KKCMTFEasingCurveEaseOutSine =       1 << 2,
    KKCMTFEasingCurveEaseInOutSine =     1 << 3,
    KKCMTFEasingCurveEaseOutInSine =     1 << 4,
        
    KKCMTFEasingCurveEaseInQuad =        1 << 5,
    KKCMTFEasingCurveEaseOutQuad =       1 << 6,
    KKCMTFEasingCurveEaseInOutQuad =     1 << 7,
    KKCMTFEasingCurveEaseOutInQuad =     1 << 8,
        
    KKCMTFEasingCurveEaseInCubic =       1 << 9,
    KKCMTFEasingCurveEaseOutCubic =      1 << 10,
    KKCMTFEasingCurveEaseInOutCubic =    1 << 11,
    KKCMTFEasingCurveEaseOutInCubic =    1 << 12,
        
    KKCMTFEasingCurveEaseInQuart =       1 << 13,
    KKCMTFEasingCurveEaseOutQuart =      1 << 14,
    KKCMTFEasingCurveEaseInOutQuart =    1 << 15,
    KKCMTFEasingCurveEaseOutInQuart=     1 << 16,
        
    KKCMTFEasingCurveEaseInQuint =       1 << 17,
    KKCMTFEasingCurveEaseOutQuint =      1 << 18,
    KKCMTFEasingCurveEaseInOutQuint =    1 << 19,
    KKCMTFEasingCurveEaseOutInQuint =    1 << 20,
        
    KKCMTFEasingCurveEaseInExpo =        1 << 21,
    KKCMTFEasingCurveEaseOutExpo =       1 << 22,
    KKCMTFEasingCurveEaseInOutExpo =     1 << 23,
    KKCMTFEasingCurveEaseOutInExpo =     1 << 24,
        
    KKCMTFEasingCurveEaseInCirc =        1 << 25,
    KKCMTFEasingCurveEaseOutCirc =       1 << 26,
    KKCMTFEasingCurveEaseInOutCirc =     1 << 27,
    KKCMTFEasingCurveEaseOutInCirc =     1 << 28
    
}KKCMTFEasingCurve;

オリジナルのイージングの式はRobert Pennerさんの式です。
>> Robert Penner’s Easing Equations

CAMediaTimingFunctionのカスタマイズは3次ベジェ曲線を使ってやるので、はずんで跳ね返ったりするバウンスの動きなどは今回は残念ながら表せないのでできないのでした。

ただ調べてみたところ、方法はちゃんとありまして。

>> How to create custom easing function with Core Animation?

Jesse Crossenさんの回答を見ると見事に解決していました。
KeyframeAnimationってパスに沿わせるアニメーションだけかと思ったら、値を配列で与えれば更新のタイミングでそれを逐次読み込んでくれることもできるみたいです。ぬっはー、すげえっすね。知らんかった。

LINEで送る
Pocket

[iOS] アプリ開発日記 – 画面遷移を再考

2012/12/25

こんにちは。きんくまです。

今HabitKeeperのアップデートの開発をしてます。
iCloud対応はいったん見送ることにしました。
実際にテストを少ししてみたんですが、いろいろと考慮することが多く結構時間がかかっちゃいそうな感じだったので。
例えば、iCloud機能を途中でOFFにした場合に、iCloudにマージされちゃってるデータをどうするのかとか、
これまでのデータをそのままにしておいて、iCloud用は別データとしてもたせるべきかどうかだとか、などなど。
ぶっちゃけ自分の頭が整理できてなくて、追っついていないって言う感じです、、。うーん。

iCloudを利用しない人もいると思うので、そっちよりもまず優先することをやろうと思いました。
一通り考えているアップデートの実装が終わったら、iCloud対応にいきたいなと。

先日ユーザーの方から、日課ごとのカレンダーがみたいという意見をいただきまして。
自分でも不便だったので、そうだよなー、これは実装した方が良いよなーと思って、
競合アプリをいくつかダウンロードして、研究してみたところ、「うわ、これやらなきゃダメじゃん。」という結論に達しました。

んで、現状のものにそのままのっけても良いのですが、アプリ内の動線が悪い気がしてきて、
もう一回アプリの画面遷移を考えることにしました。
屋台骨というか、目に見えない構成のデザイン。でも目に見える部分よりも、目に見えないここが結構大事なんですよね。
一番深いところにあるものなので、アプリ使用時の使用感が変わってくるという。

それで、画面遷移も決まったので、画面デザインもそれに合わせて一新というかマイナーチェンジしようと思い、ちまちまとデザイン作業をしとりました。
ちょっとすっきりしたかな。

hk_dev_fig2

hk_dev_fig1

※開発用なんで、英語と日本語がまじってたりして文字列とかいろいろ適当です

もう少しで画面デザインが終わるので、そしたらプログラムの作業です。

画面遷移とか画面デザインの参考になる本

今回の作業の参考になった本の紹介です。ぶっちゃけすっごくお世話になりましたw

このブログでは以前にも紹介した本です。
画面構成の考え方だとか、見た目のデザインの例も豊富に載っていて非常に良い本です。

これも良い本です。ざっくり言うと、UIのカタログ集。
いろいろなアイデアが実例で載っているので、見せ方のヒントになります。

LINEで送る
Pocket

[iOS] 日課 / 習慣 / ルーチンワークを記録するiPhoneアプリのHabitKeeper バージョン1.2にアップデートしました。あと使ったライブラリとか。

2012/12/20

こんにちは。きんくまです。

HabitKeeperがバージョン1.2にアップデートしました。
今、年末年始セールやっているので、よかったらチェックしてみてくださいませ。

今回のアップデートは、新規リピート機能の追加です。月のうちの特定の日の指定が可能になりました。

こんな感じです。

specific_date_of_month

それで、次回のバージョンはiCloud対応させようと勉強中です。
いろいろと考慮しなくちゃいけないことなどが多く、ムズイですね、、。
後回しにしちゃおうかな、、。

その他にもいろいろとユーザーの方からご要望をいただいているので、そちらも実装していきたいと思っておりますです。

んで、宣伝ばっかりだとつまんないので、今回のアップデートで使ったライブラリとか、テクとかの紹介です。

MBProgressHUD

MBProgressHUDはAndroidのToastみたいな機能を実装するライブラリです。
ポップアップでいろいろ表示できます。
今回はDBのマイグレーション作業中に出すポップアップに使いました。

>> jdg/MBProgressHUD · GitHub

ライブラリといっても、.hと.mの2ファイルだけの軽量なものです。
メインスレッドで、ポップアップを出しつつ、バックグラウンドで指定したことをしてくれます。
ソースちょっとみたらGCD使ってました。
サンプルプロジェクトを立ち上げれば、どんなものか一通りわかると思います。

HabitKeeperは他に特にライブラリとか使ってなくて、グラフ機能も自作だったりします。
(グラフのライブラリ調べたのだけど、合うやつがなかったのです。なので、もうちょっと作り込みが必要だったりするのだ、、。)

それで、ちょっと前にiOSのチュートリアルサイトのRAYWENDERLICHで人気ライブラリの投票をやってまして。
そこで、上位に入っていたのがこのMBProgressHUDでした。

>> Top 10 Most Useful iOS Libraries to Know and Love

使い方も簡単なので、そんなに人気なら大丈夫だろうと思い今回使用しました。

1から31日のフラグを4バイトにおさめるビット演算

今回のアップデートでは、1から31日までのどの日にチェックするかのフラグを管理する必要がありました。
CoreDataのAttributeで31個のBooleanフラグを立てても良いのですが、さすがに見た目が悪いのと、イマイチな実装だと思いました。

それで、ずっと前にやったプチコンでのビット演算でのフラグ管理の話を思い出しまして。

AttributeでInteger32 = 4バイトであれば、4バイト = 32ビットあるので、31個のフラグが管理できそうです。
これで1つのAttributeで31個のフラグを管理することができます。

おおこれは使うしかないと思い、今回やってみました。
ビット演算によるフラグ管理は、端末のスペックが弱かった昔のゲームなどでは使われたみたいですが、今はどうだかしらないです。
あと、今回のようにDBの容量節約+日付という同一のものを管理する今回の場合には大丈夫だと思うのですが、最近はあまり推奨されてないみたいです。
理由は単純にわかりづらいから。なんで、使いどころには注意が必要だと思います。
例えば、全然関係ないものをひとつのIntegerに入れてしまうとか。

実際のコードです。こんな感じのメソッドを用意します。

- (BOOL)specificDateFlagInFlags:(NSUInteger)flags date:(NSInteger)date
{
    if(date < 1 || date > 31){
        [NSException raise:@"date range error" format:@"date %d is out of range", date];
    }
    BOOL flag = (flags & (1 << (date - 1))) ? YES : NO;
    return flag;
}

- (NSUInteger)setSpecificDateFlagInFlags:(NSUInteger)flags flag:(BOOL)flag date:(NSInteger)date
{
    if(date < 1 || date > 31){
        [NSException raise:@"date range error" format:@"date %d is out of range", date];
    }
    if(flag == YES){
        flags = flags | (1 << (date - 1));
    }else{
        flags = flags & (~(1 << (date - 1)));
    }
    return flags;
}

//see http://stackoverflow.com/questions/1286425/nsstring-to-print-in-in-binary-format
- (NSString *)getBitStringForInt:(int)value
{    
    NSString *bits = @"";
    
    for(int i = 0; i < 32; i ++) {
        bits = [NSString stringWithFormat:@"%i%@", value & (1 << i) ? 1 : 0, bits];
    }
    return bits;
}

使ってみます。

    NSUInteger flags = 0; //初期状態
    
    //1日のフラグを立てる
    flags = [self setSpecificDateFlagInFlags:flags flag:YES date:1];
    //中身を見てみる
    NSLog(@"test1 = %@", [self getBitStringForInt:flags]);
    
    //18日のフラグを立てる
    flags = [self setSpecificDateFlagInFlags:flags flag:YES date:18];
    //中身を見てみる
    NSLog(@"test2 = %@", [self getBitStringForInt:flags]);

    //5, 24, 31日のフラグを立てる
    flags = [self setSpecificDateFlagInFlags:flags flag:YES date:5];
    flags = [self setSpecificDateFlagInFlags:flags flag:YES date:24];
    flags = [self setSpecificDateFlagInFlags:flags flag:YES date:31];
    //中身を見てみる
    NSLog(@"test3 = %@", [self getBitStringForInt:flags]);
    
    //5日のフラグを調べる
    NSLog(@"day5 is %d", [self specificDateFlagInFlags:flags date:5]);
    
    //8日のフラグを調べる
    NSLog(@"day8 is %d", [self specificDateFlagInFlags:flags date:8]);
    
    //18, 24, 31日のフラグを下ろす
    flags = [self setSpecificDateFlagInFlags:flags flag:NO date:18];
    flags = [self setSpecificDateFlagInFlags:flags flag:NO date:24];
    flags = [self setSpecificDateFlagInFlags:flags flag:NO date:31];
    //中身を見てみる
    NSLog(@"test4 = %@", [self getBitStringForInt:flags]);

出力結果です。特定の日のビットがたっているのがわかると思います。

test1 = 00000000000000000000000000000001
test2 = 00000000000000100000000000000001
test3 = 01000000100000100000000000010001
day5 is 1
day8 is 0
test4 = 00000000000000000000000000010001

というわけで、最近のプログラム環境では使いどころの難しいビット演算ですが、たまには役に立つのだ。
というお話でした。

興味のある人はググってみると良いかもです。
>> ビット演算

LINEで送る
Pocket

[iOS] 日課 / 習慣 / ルーチンワークを記録するiPhoneアプリのHabitKeeper バージョン1.1にアップデート

2012/12/10

こんにちは。きんくまです。

先週末にHabitKeeperが1.1にアップデートされました。

バージョン 1.1 の新機能

– 記録タブでチェックすると、チェックマークのアニメーションが現れます
– それぞれの日課の日々の記録をリセットすることができます
– アプリケーションの全データをリセットすることができます
– 日付が変わると、記録タブで1回だけ自動でその日に変更されます

リセット関係はユーザーから要望メールをいただきました。
実装したよとメールしたところ、喜んでいただけたので良かったです。

今のバージョンのスクリーンキャプチャをとってみました。
こんな感じです。

バージョン1.2の開発

今は別の方からいただいた要望で、月で特定の日を設定するというものを
作っております。デザインはこんな感じです。

hk121210

これができれば、

・曜日
・○にちごと
・月のうち決まった日付

のどれかで設定できるようになります。
ルーチンワークはこれでだいたいチェックできるようになるかなーと。
サラリーマンの人が給料日チェックしたりw

で、このバージョンアップの場合、DBの構造に変更を加えるので、マイグレーション(移行とか引っ越しとか)作業が必要でして。
iOSの場合はDBの構造を変えた状態で何もせずに前のデータを読み込むとアプリが落ちてしまうのです。
AppStoreで参考までにアプリをいろいろとチェックすることがありまして、そのときに「アップデートしたら起動しない〜」というコメントをたまに見かけることもあるのですが、
これが原因の場合もあるんじゃないかなーと思ってたりします。

で、そのマイグレーション、今回の単体機能追加だったらそんなに問題ではなかったのですが、
将来的なバックアップ機能との兼ね合いをどうしようかと、
うんうん考えていてあまり作業が進んでなかったという、、。
あんまり悩んで止まってしまっても仕方ないので、とりあえず気にせず次のアップデートはこれ単体でいってみようかと思っております。

LINEで送る
Pocket

[日記] 音声認識とか

2012/12/3

こんにちは。きんくまです。

前に書いたエントリの音声認識についてです。

今回読んだ本

この本をざっくりと読んでみました。
内容は、どうやって音声データを解析してそれを認識するかという原理についてです。
結論を最初に正直に書いてしまいますと、「難しくてさっぱりわかりませんでした!」

ただ、わからないながらもわかった部分は少しはあります。

音声認識(書き取り)と音声合成(発話)は違う

大前提としてわかってなかったのがこれです。
音声 → 文字
文字 → 音声
というのは、システム的にかぶるところはあるのですが別物です。

それぞれのライブラリや、有償のサービスも存在するのですが、どっちに変換するかによって使うものが違ってきます。

音声認識について

本の中に戻ります。
いろいろと難しい数式やら理論が載っていたのですが、「いかに認識の確率の精度をあげていくか」がメインの目的だと思いました。

音声データのある点の波形を周波数ごとに分解します。
そこから話されている文字が何かを当てることを考えるとします。

するとそこには考慮しないといけないことがすごくたくさんあるんです。
発話者がそもそも持つ音の特徴や前後の文脈による発音の変化、または外部の環境のノイズなど。
それらを考慮するために、確率論や統計論を駆使しているみたいです。

あと音声認識は一定の状況で最も判定が良くなるようです。
現状では様々なシチュエーションに対応できるわけではないです。

だから例えばSiriで普段よりも非常に早口になったり、逆に非常に遅く話したりしたときはうまく認識してくれません。
これはSiriで最も最適化された話し方というものがあり、そのゆらぎの範囲の中でならきちんと認識してくれるのですが、そこからはずれてしまうと上手く理解できないということです。
ゆっくりだろうと早口だろうと、それを普通のスピードで解析するためにエラーが起きてしまいます。

逆に言えば、話すスピードや話される語意なんかを一定の枠にしぼってしまえば、認識させやすくなるとも言えます。
(確率の分母が小さくなるから)

まとめ

わかってないのにまとめるのも何ですがw まとめると、

・音声認識は確率論
・確率を上げるために、似たモデル(音響モデルや言語モデル)を作る
・条件を限定した方が当てやすい

という感じですかね。
それで、実際のアプリにもし組み込むのであれば、種々ライブラリを利用することになります。

ざっと調べると

>> 大語彙連続音声認識エンジンJulius
>> 音声認識(RecognizerIntent)を使用するには Android
>> iOS SDK用音声認識ライブラリ VocalKit の使い方
>> Nuance – Nuance Mobile Developer Program – DragonモバイルSDK
>> Inspirium 汎用組込みソフトウェア : 富士通
>> 擬人化エージェントツールキット Galatea Toolkit
>> AquesTalk – テキスト音声合成ミドルウェア

有料、無料もろもろあります。あとはSiriのAPIが解放されたらいいなって

>> iOS 5.1 の音声入力を使ってアプリケーションを操作してみる

LINEで送る
Pocket

[日記] アプリ開発日記とか

2012/12/3

こんにちは。きんくまです。

前回のエントリの続きは、次回のエントリに書こうと思います。
今回は、もろもろの日記です。

アプリのアップデートの状況

拙作HabitKeeperのアップデートの申請を先週あたまに申請しました。
うまくいけば今日あたりに、アップデートの完了のエントリがかけると思ったのですが、ささいなことでリジェクトされてしまいまして。

それで、すぐに修正してまたアップロードしたので、また今週末ぐらいには結果がわかるかと。

申請した時点からさらに開発をすすめていたんですけど、gitでブランチ切ってたからすぐに申請時点にソースを戻すことができて良かったです。
一人でgitを使っててもそんなに便利さを実感することがなかったんですが、今回初めて実感できました。

テスト駆動開発とかCIとか

話は変わって、世の中にはいろんな開発手法があるようでして。
テストのやり方を前から調べてたんですが、それに付随していろんな開発手法を目にする機会がありした。

テスト駆動開発(Test-Driven Development = TDD)というのもその一つです。

1. Red(赤)テストを先に書く。この時点ではアプリのコードを書いてないので通らない
2. Green(緑)アプリ側のコードを書く。テストを通るようになる。
3. Refactoring(リファクタリング)効率化だったり、見通しが良くなるようにコードを品質改善する
4. 1に戻る

テストコードを先に書いて、次にアプリ側のコードでそのテストが通るように実装する。そのあとリファクタする。みたいな感じでやります。
なんか2重にコード書くみたいですごくめんどくさい感じです。
が、テストコードを書く時点で何をアプリにさせたいのかを考えるので、アプリ側も整理されて実装できるようです。
また、テストしづらいコードというのは、どこかに問題があるのでそれがわかるのも良いとか。

なんで、少しずつ自分も取り入れてみようと思ってます。

継続的インテグレーション(continuous integration = CI)というのも開発手法というか、開発環境というか。
ちょっと調べてみたところ、複数人で開発するときに特に力を発揮するみたいです。
これをやるためのJenkinsというおっさんのアイコンをよく目にします。

個々人が開発 > git でpush > (ここからJenkins側が自動でやる)Jenkinsでビルド、テスト > エラーがあると全員でメールを送る > 問題なければテスト環境にアップ

みたいな感じにできるらしいけど、まだよくわからないです、、。
とりあえずTDDをためしてみる。

サーバー側とか

アプリでデータベースを扱っているので、DBの扱いの勉強になるかなと思って、今まで避けていたwebのサーバー側の技術を調べてました。

クラウドだVPSだRESTだのと、いろんな用語が出てきて困ってしまったのですが、ひとつずつ調べていけば「ほうほうなるほど」ということが多く面白いです。

言語はPHPにしました。
目下の目標はライブラリなしでメモアプリを作ったあと、SymfonyやCakePHPを試してみたいなと思ってます。

LINEで送る
Pocket

[日記] Siriさん

2012/11/28

こんにちは、きんくまです。
今回はSiriさんです。

siri-1

iPhoneのSiriをよく使ってます。
何に使っているかというと、

・タイマー
・天気予報
・カーナビ

が主なところです。
使っていて、良い点や悪い点、どうしてそれが良いのかなどを考えたのでメモしておきます。

特に良く使っているのがタイマーです。
昼飯に、ラーメンとかパスタとかゆでたり、レトルトのカレーをあっためたりするんですけど、
そのときによく使っております。

後で、通常の手順と比較するために、Siriの手順を書きます。

1. ホームボタン長押し
2. ピピっとなって音声入力受付開始
3. 「タイマーを○分にセット」と言う
4. サーバー側で通信して、音声の解析が行われて、結果が返ってくる
5. Siriが「○分にセットしましたカウントダウンを開始します」といって、タイマーがスタートする

という感じです。ここで、ユーザーが行っているのは1と3の部分です。
ボタンを押して命令を話すという2点です。

通常の手順を書いてみます

1. ホームスクリーンから時計アプリアイコンを探す
2. アプリアイコンを押してアプリ起動
3. タイマータブを選択
4. ドラムから○分を選択
5. 開始ボタンを押す

ユーザーが行っているのは全ての手順です。
この間、画面をタッチして、画面が切り替わる視覚的なフィードバックを確認しつつ、次の手順にすすむということをしています。

何が言いたいかといいますと、自分の命令がきちんと理解さえすれば、Siriは早くて楽にコンピュータにその命令を行わせることができるということです。

Siriは音声入力したものを解析し、命令を実行しつつ、音声読み上げによる音声のフィードバック(画面の切り替えは補助的)を行います。
コンピュータとの関わり方が、音声をキーにしたものです。
対して、これまでのものは、キーボード、タッチの物理的な接触に基づく入力、画面の書き換えによる視覚的なフィードバック(サウンドは補助的には使われる)が行われます。

音声を使った操作(Siri) 従来
入力方法 音声 物理的な接触に基づく(マウス・キーボード・タッチ)
出力方法 メインで音声
サブで視覚的
メインで視覚的
サブで音声

なので、Siriはこれまでとは全く違った体験をすることになります。
まーSiriとか書いてるけどAndroidもしゃべってコンシェルとかあるから、「音声入力・出力にもとづくコンピュータとの対話」とか書いた方がいいかもしんないです。

文字の読み書きは習わないとできないのですが、話したり聞いたりということはその土地で話されている言語であれば自然とできるようになります。
なので学習コストとしては低いと思うので、今後はますます音声入力が活用されていくんじゃないかと。

と予想をたてたんですが、ただ現在では現実問題として向き不向きがあると思います。

音声入力のイメージとしては、機械に何かをさせるというよりは、人に何かをお願いするということに近いと思います。
何かをお願いして、「あれ?この人わかってるのかな?」みたいな感覚。
Siriの場合だと「○○ですね。わかりました」という感じになって、やっとこちら側も「わかってくれたか。ホっ」みたいな感じになります。
ただこれが単純な作業の場合は、そこまで気にならないのですが、複雑な作業をやらせようとすると、わかってないので修正するという作業が増えてくるため、イラっとしてきます。

なのであまり込み入った作業というよりは、決まりきった作業を音声を使ってショートカットで行うといったものに向いているのかなと。
音声を理解する技術が今後進歩していけば、より複雑なことがより正確にできるようになると思います。
ただ現在では、ランチャーアプリみたいなそんな捉え方をするといいのかなと。

あー、あとあれです、文字入力(フリックとかキーボードをタップ)がめんどい時も意外と役に立ちます。
英数とか記号のきりかえとかが煩雑で面倒なとき、あれです。
iOSはキーボードに音声入力のボタンがあるので、それを使ってマップアプリで住所を入力するときとか、メモアプリに取り急ぎメモとりたいときとか、とりあえずざっと音声入力。
全然違ったりすることもあるのですが、だいたい合ってたりすれば、あとは普通にキーボードで微調整。
みたいなそんな使い方もアリです。

んで、音声入出力が面白かったので音声の解析についてちょびっと調べてみた話を次回にでも書いてみようと思います。

LINEで送る
Pocket

ページトップへ戻る