(iOS 4) バックグラウンド動作するラジオアプリを作ってみる

プログラム関係の仕事をするときはたいてい、ネットラジオを使って部屋の中にBGMを流している。最近のお気に入りはSomaFMのチルアウト/アンビエント専門チャンネル"Groove Salad"だ。いい感じで生活の邪魔にならない音楽を絶え間なく提供してくれる。

つい先日ようやくiPhone 4を導入したので、できればバックグランドで動作するネットラジオアプリを入れてGroove Saladを垂れ流しにしたい。ただ、「バックグラウンドで動作するネットラジオアプリ」で無料かつ使いやすいものというのは、なかなか存在しないようだ。

まあ、無いなら自分で作ってしまおう。

ストリーミング再生

iOS 4を使ってネットラジオ的なものを作るのは難しくない。AV Foundation FrameworkAVPlayerクラスを使えば簡単に実現できる。例えばGroove Saladを再生するのだったら、以下のようにすればいい。

#import <AVFoundation/AVFoundation.h>

AVPlayer *player;

NSURL *url = [NSURL URLWithString:@"http://ice.somafm.com/groovesalad"];
player = [[AVPlayer playerWithURL:url] retain];

[player play];

基本的にはこれだけだ。

バッググラウンド再生

これもググれば必要な情報はすぐに見つかる。今回はとりあえず以下の2点をおさえておけばいいようだ。

Info.plistの設定

Info.plistの項目に"Required background modes"を追加し、"Item 0"として"App plays audio"を指定する。


オーディオセッションのカテゴリー設定

今回のアプリのようにバックグラウンドで垂れ流し再生を行う場合は、オーディオセッションのカテゴリーを「プレイバック」にしておく必要があるらしい。具体的には以下のようにする。

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

見た目

基本的にはこれだけで用件を満たすことができるのだけれど、せっかくだから見た目の体裁も最低限整えておこう。ちょうど都合のよいことに、Groove Saladの素材を制作している人がいた。

http://www.teknoel.com/desktops/

今回は個人用途なので、これを利用させていただくことにしよう。

UIは……まあこんな感じでいいか。

ビューはUIImageViewにして、画像をはめ込むことにしよう。

Retina対応のアイコンなども用意して、なんとかアプリらしく見えるようにした。


まとめ

AV Foundation Frameworkは、メディアファイルやメディアストリームを扱うのに便利なインフラだ。今回は音しか扱わなかったけれど、動画を使って遊んでみるのも面白いと思う。

iOS 4から導入されたマルチタスキングは、なんだかんだ言って便利な仕組みだ。iOS 3系との共存はちょっと面倒かもしれないけれど、とりあえずでも対応しておけば今までとは異なった体験が生み出されるかもしれない。それをスルーするのは勿体無いことだと思う。

東京ゲームショウ2010

気づいたら一週間以上ブログを書いてない。ヤバい!仕事が切羽詰ってくると時間配分の能力がどんどん低下し、複数の物事をこなすということができなくなってしまう。

そんな中、今日は視察として東京ゲームショウへ行ってきた。早朝の雨が酷かったとか、事前登録者の入場列が超待たされたとか、出鼻を挫かれることが色々あったのだけれど、まあそれはよいとして……

今年のTGSは、何かプラットフォームを大きく変動させるような重大発表があったわけでもなく、各プラットフォームの成熟期といった観があったと思う。個人的に最も注目したのは、コナミの"Castlevania -Lords of Shadow-"だった。スペインのデベロッパMercurySteamによる制作という点がちょっと驚きだ。スペインのスタジオでコンシューマ機向けのAAA狙いタイトルを制作するという事自体があまりピンとこないのだけれど、もしこれが成功すれば面白い実績になりそうだ。

KinectとMoveは、同じ会場で展示されているのを見てみると、各々のとる戦略の違いが明らかになってくるように思える。Kinectの方は、売り方次第では基本パックで完結させることも可能で、商売的にも基本パックで元が取れるよう設定されているように見える。それに対してMoveの方は、もはや基本パックで元を取ることは考えておらず、ソフトウェア側の展開にすべてを賭けているように見える。

あと驚いたのは、The Behemothのブースがやたら存在感があったということ(上の写真)。特に何か大掛かりな展開があったというわけでもなく、ひたすらCastle Crashersをプッシュしていただけなのだけれど……いったいどういう経緯があって、こんな大掛かりなことになったんだろう?

ブースと言えば、神奈川工科大学大阪電気通信大学などのブースも、意外としっかりとしたつくりになっていて驚いた。これはビジネスや就職戦略的に云々というよりも、体験学習的な意味合いが強いのかなと思う。

AR.Droneもガジェット好きの注目を静かに集めていたようだ。この手の小さめのブースにも足を運んでみると発見があって面白い。

Grand Central Dispatchでお手軽並列処理

Grand Central DispatchMac OS X 10.6およびiOS 4に追加された新技術だ。

このGrand Central Dispatch(以下"GCD")は、プログラマー以外にその効用を説明することが難しい技術だ。漠然と「マルチコアプロセッサを効率的に使うための技術」と言っておくこともできるが、それじゃあなんでiOS 4に搭載されてんの?という話になってしまう。

これをプログラマー向けに説明するならば、次のような感じになるかと思う。

GCCを拡張してクロージャ的な機能を追加してみたら、非同期処理とか並列処理とかすげー書きやすくなったんで、ちょっとその辺りまとめてみました。

僕の個人的な意見としては、単にAppleコンパイラー技術者たちがC言語ファミリー(C/C++/Obj-C)にクロージャを追加したかっただけなんじゃないかな、と考えている。

とりあえずマンデルブロ集合

とりあえず何か重たい処理を題材にしてみようと思い、マンデルブロ集合を描くプログラムを用意した。そしてそれを動作画面で比較すると効果が分かりやすいかもしれないと思い、次のような動画を作ってみた。

左が普通にシングルスレッドで書いたプログラム、右がGCDを使って並列化したものだ。フラクタルな形状なので拡大する動きはイマイチ分かり難いということに、動画を作ってから気が付いた。ごめんなさい分かり難いです。まあ、注意深く見れば、右側がかなり高速化されているということが分かるでしょう……

ソースコード

シングルスレッド版のメイン部分は、こんな感じになっている。

  for (int y = 0; y < kImageSize; ++y) {
    double c_im = kMaxIm - y * kScaleIm;
    for (unsigned x = 0; x < kImageSize; ++x) {
      double c_re = kMinRe + x * kScaleRe;
      double re = c_re, im = c_im;
      for (int n = 0;;++n) {
        double re2 = re * re, im2 = im * im;
        if (n == kMaxIterations || re2 + im2 > 4) {
          pixels[x + y * kImageSize] = exp(1.0  / kMaxIterations * n) / 2.8 * 255;
          break;
        }
        im = 2 * re * im + c_im;
        re = re2 - im2 + c_re;
      }
    }
  }

よし、それじゃあ、これをGCDで並列化してみよう。こんな感じだ。


dispatch_apply(kImageSize, dispatch_get_global_queue(0, 0), ^(size_t y){
double c_im = kMaxIm - y * kScaleIm;
for (unsigned x = 0; x < kImageSize; ++x) {
double c_re = kMinRe + x * kScaleRe;
double re = c_re, im = c_im;
for (int n = 0;;++n) {
double re2 = re * re, im2 = im * im;
if (n == kMaxIterations || re2 + im2 > 4) {
pixels[x + y * kImageSize] = exp(1.0 / kMaxIterations * n) / 2.8 * 255;
break;
}
im = 2 * re * im + c_im;
re = re2 - im2 + c_re;
}
}
});

変更箇所は赤字にしておいた。というか、書き換えたのはたったの2箇所だけだ。

GCDに初めて触れる人にとって、まず気になるのは、1行目末尾の"^(size_t y){"の辺りの記述だと思う。これが例の「C言語クロージャ的なもの」であり、いわゆるラムダ式、あるいは無名関数のようなものだ。Appleはこれをblocks拡張と呼んでいる。

ここでは、このblockをdispatch_applyの引数に与えることで反復実行している。dispatch_applyによってグローバルキューに積み上げられたkImageSize個のblockは、GCDによって(可能であれば)コンカレントに実行される。

CPU使用率

アクティビティモニタでも確認してみた。これが元のプログラム。

GCDを使ったプログラムがこれ。

どの程度効率的に動いているかは分からないけれど、並列化されたうえで複数のコアを使い切っているのは確かなようだ。

感想

わりと何も考えずにほんの少しの変更だけで、いちおうのタスク並列化を実現できてしまうというのは、なかなかに素敵なことだと思う。

しかしながら、GCDが専らこのような並列化のための機能なのかというと、どうもそういう感じはしない。それでは前述のようにiOSに搭載する意味が無いからだ。

iOSにおけるGCDは、主に非同期処理の記述を簡単にするという目的で使われているようだ。今回の使い方にしてみても、「GCDは並列処理の記述を簡単にする」という解釈が可能だ。つまり、「記述を簡単にする」が主目的であり、その結果としてもたらされる並列処理だとか非同期処理だとかは、副次的なものであると考えることもできる。

そう考えると、これはやはり「Blocks拡張によって何が便利になるか」という視点に基づいて構築されたものなのだろうと思われてくる。あくまでもGCDは技術としてのラッピングであり、blocks拡張こそが真の目的であったのだ、と……

CEDEC 2010 三日目

三日目のCEDECMIT石井先生の基調講演から参加した。いわゆる「タンジブル」という言葉にはバズワードの匂いを感じるものの、最先端の研究者であるところの石井先生が使う分には差し支えない。他の人が語ったら絵空事になってしまいそうなことを、説得力を持って理論展開することができるというのは素晴らしいことだ。基調講演として最適なテーマだったと思う。

石井先生が紹介したものの中で個人的に好きだったのは、musicBottlesというプロジェクトだ。瓶の蓋を開けると音楽が流れてくる。まるで、蓋を開けた香水の瓶から香りが流れ出てくるように。「瓶の蓋を開ける」という、大昔から人々が日常の中で繰り返してきた物理的なアクションを、デジタルな機構の中のインタフェースとして融合させたものだ。

この日のセッションの中で個人的に最も参考になったのは、セガの長谷川さんによる「海外協業に役立つGDD、TDDの書き方」だった。ちなみに、GDDというのはGame Design Documentの略であり、TDDはTechnical Design Documentの略だ(Test Driven Developmentではないよ)。

海外のパブリッシャーとの協業においては、本制作へと入る前に、ゲームデザインの全体像をまとめた文書―GDDと、技術的な方針についてまとめた文書―TDDの提出が求められるという。これらの文書は、ゲームを構成する要素の全体に渡って詳細な記述を行うことが求められており、その分量は100ページ余から電話帳サイズになることもあるという。これらの文書がちゃんと用意できなければ、本制作に入ることは許されないというのだ。

一昨日の「はじめての日米共同開発」でも語られていたように、昨今の欧米の開発スタイルにおいては、全ての作業のベースとして詳細な文書を作成することが求められるらしい。僕は今回のCEDECを通じて初めて、そのシリアスさについて知ることができた。

僕は欧米のパブリッシャーと直接やりとりした経験は無いけれど、このセッションを受けることによって、以前から持っていたいくつかの疑問を解くことができた。欧米のパブリッシャーがマイルストーンと文書に対して厳密さを求めるというのは、是非とも多くの人に知っておいてもらいたいことだ。

CEDEC 2010 二日目

今年のCEDECは興味のあるセッションが重なってしまっていて、どれを受講しようか迷うことがある。会社に所属していれば同僚と分散して受講するという作戦も取りうるのだけれど、単身での参加の場合はそうもいかない。事前情報だけから内容を想像して出席を決めるというのは、もはやバクチに近いものがある。

株式会社ポケモンの石原さんらによる「人を楽しませるプロデュース」は、ポケモンドラクエという業界トップIPにおける戦略の対比から、巨大IPのプロデュースのありかたについて知る、というような内容になっていた。ただ、全体的にポケモンの方が話題の中心になっていたように思われる。「株式会社ポケモンがあるからできること」「株式会社ドラクエが無いからできないこと」という意見が石原さんの口から語られるとき、それは圧倒的な説得力を持つように感じられた。

大塚康生さんと上田文人さんの対談は、単に大塚さんの講演としてみた場合に、とても面白いものだった。ただ残念ながら、対談として話が噛み合っているとは思えなかった。これは対談形式にするよりも、大塚さんにひたすら喋ってもらうというスタイルにした方が良かったんじゃないかなと思う。

この手のパネルトークは話題が様々な方向に飛んでいくため、単なる文字起こしではないレポートにまとめることは、なかなか難しい。もし会社からレポートの提出を義務付けられているならば、パネルトークよりも普通のセッションに参加した方が賢明かもしれない。パネルトークは聞いて楽しめるものであることが多いので、個人的には嫌いではないのだけれど……

任天堂の小泉さんによる「スーパーマリオギャラクシーを作る。」では、スーパーマリオギャラクシーにおけるユニークなゲームデザインが生まれた経緯について、とても丁寧な解説を展開していた。それらのデザインはすべて、過去作における困難を克服するための施策だった、というのはとても興味深い話だ。ここまで徹底的にゲームデザインを中心に据えた制作スタイルというのも、もはや珍しいものかもしれない。何かにつけて多くの要素を背負い込みがちな昨今の制作現場において、その徹底ぶりは羨ましくも感じられる。

さあ、明日は最終日だ。明日は基調講演から参加しようと思う。

CEDEC 2010 一日目

フリーになってからCEDECには自腹で参加している。去年は一日だけの参加だったのだけれど、今年は思い切って三日間全部の参加にしてみた。一日だけの参加だと、どの日を選ぼうか迷ってしまう。うだうだと迷って時間を無駄にするぐらいだったら、もういっそのこと、三日間フル参加を義務として自分に課してしまうのがいいんじゃないかと考えた次第だ。

一日目から聴きたいセッションが重なってしまい、どれを受講しようか迷うことがあった。迷いながら選んだセッションの中でも、個人的に最も興味深い内容だったのは、スクウェア・エニックスの塩川さんと松澤さんによる「はじめての日米共同開発 〜日米両国でのディレクション経験を通じて得た、たくさんの気づき〜」だった。

日本人が何となくイメージする「欧米的な開発スタイル」のイメージと、その実像との間にあるギャップを、3つの項目にまとめて簡潔に解説していた。これは単に共同開発の際に役立つ知見であるというだけでなく、日本の現場が単独で海外志向タイトルの開発を行う際にも役立てることのできる知見であったと思う。

特に「ビリーバブル」(believability)という言葉は、向こうの嗜好を理解するにあたって重要なキーワードだと思う。彼らが求めているのは「リアルであること」ではなく「ビリーバブルであること」、つまり「それが作品の中において信じられる・説得力を持つものであるという感覚」なのである、と。これだけで全てが片付くわけではないけれど、最も重要でありながら、最も勘違いされることの多い点であると思う。

もうひとつ、メディアクリエイトの細川さんによる「次なる高みへ。ゲームビジネスの近未来像」も興味深い内容だった。実は僕は遅刻してしまい途中からの受講だったのだけれど、それでも十分に参考になる話を聞くことができた。ソーシャルゲームユーザとコンシューマゲームユーザ(現役ユーザー・元ユーザーを含む)の間にある関係性の分析を見るのは、僕は初めてのことだった。今後さらに詳しい分析が行われるようであれば、ぜひそれを見てみたい……と思わせられてしまうのは、さすがは商売上手と言ったところなのか。

iPhoneゲーム開発本が届いた

O'Reilly Japan - iPhone/iPadゲーム開発ガイド――Objective-Cで作る2D/3Dゲーム

巻末付録を担当させていただいた例の本が届きました。発売は来週ですが、CEDEC会場にて先行販売を行うそうです。オライリー・ブースへお立ち寄りの際は、ぜひお手にとってみてください。

この付録記事で解説しているのは、こんな感じのプログラムです。

ソースコートiPhone/iPadの両方で動くユニバーサル形式になっていますので、iPhone上で動かすことも可能です。ただ、この手の「触って楽しむ」系のアプリは、やはりiPadぐらいの大きさがあった方が、手応えが感じられて楽しいですね。