
手順の概要
Windowsには、音声合成(SAPI)という機能が搭載されています。これをつかうと、Excelや、Vectorでダウンロードできる各種SAPI対応アプリケーションでテキストを読み上げさせることができます。
※なんでWordじゃないのかは謎。
ただし、Windows7のProfessional程度では英語のランタイムしか搭載されていないので、日本語や中国語を読み上げるためには別途ランタイムが必要。このランタイムがどうも無料で手にはいらないっぽい。UltimateのDVDに入っているという噂。
一方、SAPIとほとんど同じ機能なんだけど微妙に異なるぽいSpeech Platform Server Runtimeというのがあって、これは各言語ランタイムが無料で配布されている。そして、Speech Platform Server RuntimeをSAPIとして認識させちゃう裏技があるので、これを使えばExcelでテキストを読み上げさせることが出来る!
Microsoft Speech Platformとランタイムのインストール
Download: Microsoft Speech Platform - Runtime (Version 11) - Microsoft Download Center - Download Detailsから、自分の環境にあったSpeechPlatformRuntime.msiをダウンロードしてインストール。Windows7 64bit版の人はx64_SpeechPlatformRuntime、32bit版の人はx86_SpeechPlatformRuntime。「わかんない」というような人はきっと32bit版です。
Download: Microsoft Speech Platform - Runtime Languages (Version 11) - Microsoft Download Center - Download Details
から、必要な言語のTTSランタイムをインストール
※「zh」とか「ja」で検索すれば見つかる。
※「MSSpeech_SR」で始まるのは音声認識用ランタイム、「MSSpeech_TTS_」で始まるのが音声合成用ランタイム。今回必要なのは音声合成用ランタイムなので、間違えないように注意。
Speech Platform Server RuntimeをSAPIとして認識させる
スタート > すべてのプログラム > アクセサリ > コマンドプロンプトを右クリックして、「管理者として実行」。権限昇格のために管理者パスワードを要求させるので入力。開いたコマンドプロンプトで、下記を実行する。
reg COPY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech Server\v11.0\Voices\Tokens" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens /s /f※または、レジストリエディタを立ち上げて、図のようにコピーしてもよい。
音声合成(SAPI)の言語を変更
「コントロール パネル > すべてのコントロール パネル項目 > 音声認識 > 音声合成」を開いて「音声の選択」で適切な言語を選ぶ。
※ここまでの手順が失敗しているとMicrosoftAnnaしか出てこない。その時はおやつでも食べて考え直す。
Excelで読み上げ
読み上げコマンドが表示されない - Word - Office.comを参考に、読み上げコマンドを表示させる。
Excelのセルに適当な文章を入力して、読み上げボタンを押すと読み上げられる。
謝辞
キーとなったレジストリの変更のアイデアを初め、だいたいのアイデアは下記が出所です。このブログ記事は、下記を元に、最近の環境で実行できるようにまとめ直しました。日本語や中国語等の音声合成(SAPI TTS)を無料で使う方法(Speech Platform Server Runtimeを裏技で SAPI 5.1として動作させる方法)
あけましておめでとうございます。初日の出は見に行ったけれど、正月とかあまり気にせず元日からコードを書いています。
さて、お正月にちなんで、ひたすら寝ているプログラムsleepUntilというのを書いてみました。sleepじゃなくてsleepUntilなので、指定した時刻までただ寝ているプログラムです。
sleepUntil (mogya's gist: 1550431 -- Gist)
なんに使うかといいますと、プログラムを夜中に走らせるために使います。
スクレイピングは人が活動していない時間帯に走らせるのが基本なので、夜中1時スタートというのが普通です。これまでは、時計を睨みながらsleep 3000; とかしていたのですけれど、そんな計算は自分でしてくれるプログラムがsleepUntilというわけです。
$ sleepUntil "1:00"って書けば、sleepUntilは起動と同時に眠りについて、夜中一時に(起きて即座に)終了します。
$ sleepUntil "1:00";(夜中に走らせたいコマンド)という具合にしておけば、sleepUntilが深夜一時に終了したあと、(夜中に走らせたいコマンド)が実行されます。実質的に、夜中一時に該当プログラムを起動するようなことができるわけです。
cronでいいじゃないかと言われたらそのとおりなのですけど、一回しか実行しないようなものをcronに書くのはなんだか気がひけるのです。 実行環境が違うとかそういうことも気にしなくていいですし。
時刻のパースはTime.parseに丸投げです。パースしてみて過去の時刻になったときは翌日の時刻に読み替えるようになっています。
【はじめに】
この記事は、@astronaughtsさん企画の「Titanium Advent Calendar 2011」向けに書いています。
@astronaughtsさんは、この企画もそうですけど、それ以外にも関西で最大規模のTitaniumイベントTi.Developers.meetingの主催者でもあります。最初はどうしようかと思うくらいしょぼかったw Ti.Devs.me、諦めずに開催を繰り返して大きなイベントに育て上げた@astronaughtsに、個人的今年のTitaniumMVPを送りたいです。
さて、そんなわけでTitaniumの話題を一つ。Titaniumでは、アプリ内でブラウザが開くwebViewという仕組みを使うことができます。
これを使うと、アプリ内でWEBページを見てもらうことができるので、Titanium以外でもよく使われている仕組みです。これ、意外と怖いということはご存知ですか?
俺ブラウザ -- Gist
このアプリの最後に、ちょっとスパイスをかけてみます。
上野駅が蒲田駅に変わってしまいました。これで、モバイラーズオアシスの中の人は、「蒲田駅を検索したら違う位置が表示された」という謎のバグ報告に悩まされることになります。クックック。永久に悩み続けるがいい...
ご自分のアプリのWebViewに上記を仕掛けるとか、絶対やめてください。やめろってば!
冗談はさておき、技術的にこういうことが可能であることは頭においておく必要があります。今回は上野が蒲田になる程度ですみましたが、ニュースサイトの内容を書き換えられたら?ログインしたときにユーザー名とパスワードを他のサイトに送信する仕組みが入っていたら?
webViewとブラウザを同一視していると、あっと驚く手品に巻き込まれてしまうかもしれません・・・
逆に、この手法をうまく使えば、スマートフォンに最適化されていないHTMLに別のCSSを適用して要素を大きく表示させたり、サイドバーを隠してスマートフォン向けのページに見せるようなこともできるかも。
...できるかもしれないのですけど、実際は結構大変です。この記事を書くために色々試したのですけど、evalJSしたJSコードをデバッグする手段が無いので、泣きそうでした。
ちょっと複雑なJSを書くと、なぜか処理が行われなくて途方にくれます。いい思いつきだと思ったんだけどなぁ。
【おわりに】
明日は@rakiさんかな。よろしくおねがいします〜。

ブログやWEBサイトに地図を表示することが出来て大変便利なGoogleMapsAPIに関して、Googleが有料化を発表したのでビックリしました。
Googleは、Google Maps APIの利用規約を今年4月に改定し、10月1日から同APIの利用上限を定めることを発表していた。
現時点で利用上限を超過しても、即座に課金されることはない。利用者には、APIの利用状況を確認する期間が与えられる。その上で、利用上限を超えている場合には「2012年初めごろ」から強制的に課金されるとしている。その場合は、最低30日前に通知されるとしている。
(Google Maps API有料化の詳細発表、該当ユーザーは2012年初めに強制課金開始 -INTERNET Watch)
今一番知りたいことは「どれくらい使ったら課金されるようになるのか」だと思うのですが、自分が調べた範囲では、あまり気にしなくてよさそうです。根拠はこれだ!
(FAQ - Google Maps API Family - Google Code)
Styled Maps というのは最近出来た機能で、GoogleMapsから線路を消したり海の色を変えたりといったデザイン変更が出来る機能です。こちらを使っている場合はちょっと厳しいのですけど、そうでない場合は 25,000 map loads / Day。1ページに大量の地図を埋め込むことは普通ないので、つまり実質25,000 PV/Day ≒ 75万PV/月ということになります。
モバイラーズオアシスが10万PV程度なので、食べログさんとか、大手不動産業者さんレベルにならない限りは課金されないんじゃないかと。30min.さんあたりが微妙なラインかなぁ。
さらに上記ページを見ると、越えた場合の課金金額も書かれています。
(FAQ - Google Maps API Family - Google Code)
25,000を越えたあと、1,000usageごとに4$だそうです。例えば100万PV/月のサイトがあったとすると、約3万3千アクセス/Dayなので超過部分が8300usage=$32。$960/月なので、76,800円/月ということになりますね。
ちなみに、Google Maps API Premier、お値段を公開している代理店を見つけました。85万円/年~だそうです。
GOGA - Google Maps API
回数は、APIライブラリの読込回数です。ということは、iPhoneアプリなんかは、アプリを起動して地図を表示するごとに1回と考えれば良さそうですね。
ANN:Google Maps APIへの使用制限の導入について - Google-Maps-API-Japan | Google グループ
iOS5のMobile Safariから使えるようになったHTML5・CSSを試してみました【前編】 - くらげだらけ(くだくらげのBLOG)で、Web Symbols typefaceというテクニックが紹介されていた。
WebFontという技術を使って、文字の代わりにボタン画像なんかを埋め込んだフォントを使えば、画像ファイルを持たなくてもよく使うアイコンを表示できるよ!というアイデア。
みんながこのフォントを使うようになって、jQueryみたいに高速なサーバからこのフォントが落とせるようになれば面白い技術だと思う。
でも、iOSに限定していいんだったら、[titanium]画像を使わずにボタンを表示の手法を使ってWebFontなしにボタン画像を表示することも出来る気がしたので、やってみた。
![]()
machine dependent charactors on iOS5 - mogya
理屈は前回と同じ。Apple SymbolsやLucida Grandeといったフォントは、上記のようなデザインの文字を元々持っている。これらは、同じフォントを持っていないと表示できないからWEBの世界では使わないことになっているけれど、iPhone専用サイトと割り切るのであれば、CSSでフォント指定して上げれば表示することが出来る。
どんな記号が使えるかは、下記を参考に。
長所としては、WebFontを使うより当然高速軽量に表示が出来る。短所としては、iOSの持っているフォントに依存してしまうので、昔のIE専用WEBページと同様、他の機種で見た時の表示が保証されない。
実際問題としては、サンプルをひらいてみると分かるようにWindowsでもけっこう表示できちゃうんだけど、WEBの精神から行くとあんまり望ましくないことなのは事実。「iPhone」といったらiPadもAndroidも含めた全てのスマートフォンで動くものを想像されるお客さまも日本にはいらっしゃるので、利用する時は慎重に利用することをお勧めします。

PHPな人が集まって一晩中開発を行うイベントPHP祭りに行って来ました。
「mogyaさんPHP祭りは来ないの?」というような経緯です。
「最近PHPは全然書いてないのでノーチェックですねぇ。」
「増井さんを呼んでTitaniumの話をしてもらうよ」
「今申し込みました(即答)」
実際行ってみたら、
masuidrive「この中で、Titaniumをご存知のかた?」(挙手)って言われました。そりゃまあそうですよね。
masuidrive「Titaniumでプログラムを書いたことがある方」(挙手)
masuidrive「Titaniumでアプリを作ってリリースしたことのある方」(挙手)
masuidrive「今日は初心者向けなので、今挙手された方が聞くような内容はありませんw」
ハッカソンでは、電源検索の無料版「電源検索Lite」を開発して「Titanium大賞」をいただきました。
そういうわけで、「電源検索Lite」for iPhoneは今Appleで審査中なので、審査が通ればAppStoreに登場する予定ですので、楽しみにお待ちくださいませ。
ちなみに、待ち切れない方は、電源がないお店も検索できる有料版がすでにAppStoreに出ております。
Titaniumで作ったiPhoneアプリに広告を出す場合、モジュールが簡単に手に入るAdMobが人気ですが、AdMaker(MediaAd)は使えないの?という声も多いみたいです。やってみたら簡単に出来たので、やり方をまとめてみます。
モジュールを使う
下記を落としてきます。tryden/TiAdMaker - GitHub
titanium.xcconfigを開くと、TitaniumSDKのバージョンが定義されているので、これを自分の好みのものに書き換えます。1.6.1はちょっと微妙ですね。
で、build.pyを走らせるとモジュールが出来上がります。
出来上がったモジュールを解凍して、新しいプロジェクトにこんな感じで配置。
example/app.jsにサンプルがあるので、まずはこれを動かしてみるのがいいんじゃないかと思います。
AD_URL、SITE_ID、ZONE_IDはAdMakerでメディアを作るともらえます。
というわけで起動してみるとこんな感じ。
めでたしめでたし。
webviewを使う方法
ちなみに、AdMakerの公式サイトでは、こんなふうに案内されています。
TitaniumへSDKを実装できません。どうすればいいですか?
SDKでの対応はしておりません。
Web Viewを作って頂き、そこにJavaScriptタグを実装して頂くことで表示して頂くことも可能です。
(よくあるご質問|スマートフォン広告なら「mediba ad」|iPhone、Androidアプリ・サイト広告)
JavaScriptと空っぽのbodyタグを書いたHTMLを用意してwebviewで開いたところ、広告はちゃんと表示されたのですけど、クリックしたあとの広告もwebviewの中で開いて、どうしてくれようかという感じになりました(当たり前ですね)。
webviewのイベントをハンドリングしてあれこれという手も考えられるのですが、あんまりやると広告に手を入れているように見えてしまうことが懸念されます。モジュールが動くのだったら、そのほうがいいんじゃないかな、と思います。
P.S: Android用はこちら。
titanium の AdMaker モジュール作ってみました(Android用) #titaniumjp - harukazepcの日記
「安くて飲み物がおいしいのに混んでなくて快適な喫茶店」は、つぶれる。

Twitterのつぶやきを見ていたら、わりと常識に縛られないタイプの方なのに、「新人研修で覚えてもらうのはホウレンソウとプログラミングくらいかなぁ」的なことを言われていて。そういえばホウレンソウって必須でもなんでもないことは意外と知られていないなぁ、と思ったので書いてみる。
ホウレンソウに頼ったAくんの仕事の進め方
- 9:00 業務開始。朝Mtgで、その日やることをみんなの前で発表。ぼく早くプログラム書き始めたいんだけどな...
- 9:30頃 昨日の進捗報告に上司からツッコミが。詳細な説明を書いて返信する。
- 10:00頃 ようやくプログラムを書き始める。
- 12:00 お昼休み。
- 13:00 再びプログラムを書き始める。
- 14:00 今朝のメールに上司は納得しなかったらしく、呼び出された。状況を説明してようやく納得してもらう
- 15:00 えーと。何してたんだっけ。あれ。このあと進捗会議か。
- 15:00 さっき上司に説明したばっかりの状況をもう一回みんなに報告。みんな興味ないから聞いてないんだけどね。
- 18:00 延々と関係のない人たちの状況を聞かされて、ようやく終了。晩御飯食べに行きますか。
- 19:00 定時後はプログラミングの時間だ!
- 22:30 今日の進捗をメールに書いてMLに投げる。メールボックスに届いている他のメンバーからの進捗報告は、興味が無いのでまとめてゴミ箱へ。
ホウレンソウに頼らないBくんの仕事の進め方
- 9:00 業務開始。昨日思いついたアルゴリズムを猛然と書きはじめる。
- 9:30頃 マネージャさんが後ろを通った気がしたけど、猛然とプログラムを書いていたら通りすぎていった。用事があればまた来るでしょ。
- 12:00 お昼休み。
- 13:00 再びプログラムを書き始める。
- 14:00 マネージャさんが後ろから覗いた気がしたけど、猛然とプログラムを書いていたら去っていった。用事があればまた来るでしょ。
- 15:00 一休みしていたら、マネージャさんが走ってきた。手が空くのを待っていたらしい。
「様子はどう?」と聞かれたので、進捗を説明。納得の行かないところにはツッコミが入るけど、説明したら納得してくれた。1vs1の会話だから、所要時間は15分もあれば十分 - 15:30 再びプログラムを書き始める。
- 18:00 仕事終わり。スポーツジムによって帰ろう!
進捗の把握は誰の仕事?
じつは、AもBも自分が経験したことのある仕事です。Bは夢物語だったわけじゃなくて、実際にそういうふうに仕事をしていました。ラピュタは本当にあったんだ!(海の向こうに)- Aでは、進捗を報告するのがメンバーの責務になっています。Bでは、進捗を把握するのはマネージャさんの仕事です。だってマネージャってマネジメントする人でしょ?
- 進捗会議で全員の時間を束縛するより、1vs1を繰り返したほうが、進捗把握に係る工数は少なくなります。わかりきっているところはカットできるし、わからないところはその場で聞き返せるので、マネージャさんの理解度も高いです。
- 進捗を把握するのはマネージャさんの仕事であってメンバーの仕事ではないので、マネージャさんはメンバーの仕事を邪魔しないように、忙しくなさそうな時間を見計らって進捗を聞きに行きます。「忙しいところ悪いけど、進捗を聞かせてもらえるかな?」
とはいえ、マネージャとメンバーは同じ目標に向かって進むチームなので、メンバーも可能な限りマネージャさんがヒアリングしやすいように協力しますけどね。 - Bの問題は、マネージャさんが異常に忙しいことです。メンバーが日報を書かなくていいのも、進捗会議に出席しなくてもいいのも、マネージャさんが進捗を聞いて回っているからこそです。
マネージャさんは大変ですけど、メンバーより多くお給料が出ているんだから、メンバーよりたくさん働くのはとても正しい姿ですよね。
メンバーはお互いの仕事の進捗を知らなくて、マネージャさんだけが全ての進捗を把握することになるので、誰かがコケたときに他の人がカバーすることはできません。
各人の責任範囲が明確で、メンバーの役割がはっきりしている欧米型の仕事の進め方だからこそやれるやり方なのだと思います。
でも、ここで書いたのは、実際にぼくがメンバーとして働いたことのある体験談なので、これで仕事が回っている職場が実在します。というか、日本以外で働いたときはたいていこのやり方でした。
日本式に、メンバーが状況を報告したり、やばい時に自発的に動く能力を持っていることは、別に悪いことではないです。やばい時に自発的にアラーム上げてくれたら、マネージャさんは進捗を聞いてまわる頻度を下げることができるし、メンバーの報告だって下手であるよりは上手なほうが嬉しいに決まってます。
でも、そうじゃないと仕事が回らない状態が常識だと思っているとしたら、世の中そうじゃないやり方もあるんだよ、という話も知っておいていただけると嬉しいです。
関連記事
個人的なポリシーで、アプリケーションのバージョン番号は、1.0, 1.1, 2.0とかじゃなくて、20110923, 20110925...っていうふうに年月日でつけることにしています。
どこでマイナーバージョンを上げてどこでメジャーバージョンを上げるかとか悩んでも仕方ないし、ユーザーさんにとってはどっちが新しいかさえ分かればOKなんだから、無理に数字に丸める理由はないよね。
というような経緯で俺ポリシーを採用していたら、えらい目にあいました。
理由は知らないんだけど、Titanium MobileはInfo.plistに書いてあるBundleVersionの後ろに、タイムスタンプをくっつけてしまいます。例えばInfo.plistに「1.0」と書いた場合、実際のビルドに使用されるCFBundleVersionは「1.0.1316956026」という具合に。
普通の人はバージョンなんてせいぜい5文字だから、
日付時刻をつけても弊害はなかったのだけれど、年月日方式だと、「20110925.1316956026」となってしまいます。実はバージョン番号には18桁までという制限があるので、これだとCode SignをするときのVelificationでエラーになってしまうのです。
厄介なことに、このアプリの旧バージョンはXCodeで開発していたので、年月日方式ですでにリリースしてしまっています。
しょうがないので、「3.0」にしてみたんだけど、これも「The key CFBundleVersion in the Info.plist file must contain a higher version than that of the previously uploaded version.」ということでどうにもならなくて泣きそうに。Adhoc Buildまで無事通って、最後の最後に発覚するので心理的ダメージがでかいです。
そういうわけで、このTitanium Mobileの余計な処理を止める方法。
builder.py ( /Library/Application Support/Titanium/mobilesdk/osx/#{TITANIUM_SDK_VERSION}/iphone/ )をひらいて、この辺をコメントアウトする。
僕から見たら余計な処理だったけど、書いてあるからには必要な理由があったのだろうから、普通の人はまねしない方がいいと思う。 バージョン番号が長くなって困った方だけ、自己責任でどうぞ。
おまけ:Distribution Buildのハマリどころ
iPhoneアプリの開発は、エミュレーターで動いて、AdHocビルドも動いているのに、最後の最後でリリースできない!って苦労することが多い気がする。 自分が今回はまった点と解決策。
- Distribution Buildした後、Validateするとすっごい長いエラーダイアログが出る
→キャプチャしておくのを忘れたんだけど、ほぼ画面いっぱいのエラーダイアログ。長すぎて結局何がエラーなのか全然分からなかったんだけど、ダイアログの上でcommand+Cを押すと全文がコピーできるので、エディタに貼り付ければ内容を見ることが出来る。
- 「Icon specified in the Info.plist not found under the top level app wrapper: icon.png Unable to verify icon dimensions, no icon found」
→可能性1:info.plistに書いてあるアイコンファイルと実際においてあるアイコンファイルの名前が違う。大文字小文字にも注意。
→可能性2:アイコンファイルが8bit pngになっている。24bit pngじゃないとダメらしいです。
- 「a sealed resource is missing or invalid」
→Resourcesに余計なファイルがあると起きるらしい。.gitとか.gitignoreとかそのへんをひと通り削除したら出なくなった - 「CFBundleVersion must be no longer than 18 charactoers」
→上に書いたとおり。「バージョン番号は18文字以下でないといけません」。
CodeSignとかMobileProvisioningになってしまえば、もはやTitaniumMobileであることはあまり関係が無いので、「エラー文字列 iPhone」でググるのが王道のような気がしました。

