Hatena::ブログ(Diary)

Over&Out その後 このページをアンテナに追加 RSSフィード Twitter

2015-06-24

【iOS9】Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜

昨日開催された「WWDC2015報告共有会@ネクスト」にて、iOS 9 で追加された新しい Extension Point のひとつ、「Audio Unit Extensions」についてLTをさせていただきました。



概要

Audio Unit とは?
  • Core Audio においてもっとも低レベル(ハードより)に位置するフレームワーク
  • 低遅延での音声処理が可能
  • ユニット同士を繋げて複雑なオーディオ処理を実現可能
  • iOS 8 より AVFoundation に AVAudioEngine が追加され、Audio Unit の利用ハードルがグッと下がった

Audio Unit Extensions とは?
  • iOS 9 で追加された Extension Point のひとつ
  • Audio Unit をアプリ間で共有できる

→ つまり自作エフェクトや他社製エフェクトを繋げてこういうこともできるようになる!


f:id:shu223:20150624072335j:image:w600

(※写真はイメージです)


  • Audio Unit にはエフェクト以外にもさまざまなタイプがある
    • GarageBand では Audio Unit Extensions の楽器を利用できるようになるらしい。
var kAudioUnitType_Output: UInt32 { get }
var kAudioUnitType_MusicDevice: UInt32 { get }
var kAudioUnitType_MusicEffect: UInt32 { get }
var kAudioUnitType_FormatConverter: UInt32 { get }
var kAudioUnitType_Effect: UInt32 { get }
var kAudioUnitType_Mixer: UInt32 { get }
var kAudioUnitType_Panner: UInt32 { get }
var kAudioUnitType_Generator: UInt32 { get }
var kAudioUnitType_OfflineEffect: UInt32 { get }
var kAudioUnitType_MIDIProcessor: UInt32 { get }

Audio Unit Extensions の利用方法

WWDC のサンプルコード "AudioUnitV3Example" に入っている "FilterDemo" というアプリには、Audio Unit Extensions が含まれています。まずはこのアプリをインストールして、「エクステンション利用側」を実装してみます。


利用可能なユニットのリストを取得する

iOS 9 で追加されたクラス AVAudioUnitComponentManager の `componentsMatchingDescription:` メソッドを呼ぶと、

var anyEffectDescription = AudioComponentDescription()
anyEffectDescription.componentType = kAudioUnitType_Effect
anyEffectDescription.componentSubType = 0
anyEffectDescription.componentManufacturer = 0
anyEffectDescription.componentFlags = 0
anyEffectDescription.componentFlagsMask = 0

availableEffects = AVAudioUnitComponentManager.sharedAudioUnitComponentManager()
    .componentsMatchingDescription(anyEffectDescription)

利用可能な Audio Unit の AVAudioUnitComponent (ユニットのタイプや制作者などの情報が入っているクラス)のリストが得られます。


この中に、インストールした"FilterDemo"サンプルが contain しているユニット "FilterDemo" も入ってきます。


ユニットを適用する

以下の手順で、所望の Audio Unit をサウンドに適用します。

  1. AVAudioUnitComponent の AudioComponentDescription (構造体)を取得する
  2. AVAudioUnit を `instantiateWithComponentDescription:options:` で生成する(このメソッドは iOS 9 で新規追加)
  3. AVAudioEngine に attachNodeする
  4. エフェクトノードと、プレイヤー・ミキサー等のノードを `connect:to:format:` で接続する

※AVAudioEngine を用いて Audio Unit のエフェクトをかける基本的なサンプルは、iOS8-Sampler にも入っているので、よろしければご参考に。


f:id:shu223:20150624072630j:image:w200

(iOS8-Sampler の "Audio Effects" サンプル)


Audio Unit Extensions の作成方法

なんと、Xcode 7 beta には Audio Unit Extensions を作成するためのテンプレートがまだありません(という話は WWDC セッション内でも話されています)。とりあえず現状では "FilterDemo" からコピペして使ってくれ、とのこと。


Audio Unit の関連記事


2015-06-22

【iOS9】Core Image の新機能:文字認識/追加フィルタ47種

先日、Gunosy さん主催の勉強会「WWDC Afterparty Roppongi」にて標題の発表をさせていただきました。



タイトルの通り、iOS 9 の Core Image の新機能について紹介&デモ *1 しました。


概要

大きく分けて、文字認識、新フィルタの紹介の2つ。


文字認識

WWDC初日に書いた下記記事でもわりと反響の大きかった機能。


で、OCR的なものを期待していたわけですが、リファレンスで CIFeatureTypeText を見ると、認識結果の文字列が入ってくるプロパティはないので、文字の「内容」を認識するのではなく、文字の「領域」を検出するものでした、という話。

class CITextFeature : CIFeature {
    
    var bounds: CGRect { get }
    var topLeft: CGPoint { get }
    var topRight: CGPoint { get }
    var bottomLeft: CGPoint { get }
    var bottomRight: CGPoint { get }
}

いわゆる「顔認識」も、「誰の顔か」を認識するのではなくて、顔の「領域」を検出するものがほとんどなのと同様ですね。


それはそれとしてOCRの前処理とかに便利だと思います。実装は非常に簡単で、顔認識とかとほぼ同じです。

let image  = CIImage(CGImage: imageView.image!.CGImage!)

let detector = CIDetector(
    ofType: CIDetectorTypeText,
    context: nil,
    options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])

let features = detector.featuresInImage(image)

for feature in features as! [CITextFeature] {
    // 認識結果の矩形を描画する処理
}

NDAのため iOS 9 での実行結果スクショを貼るのは自粛しますが、デモでは以下の2種類の画像について試し、


f:id:shu223:20150622065519p:image:w450



f:id:shu223:20150622065439j:image:w320


  • 前者は文字領域を完璧に検出
  • 後者はGitHub マークのある黒地に白文字の "shu223" というものしか認識されず

という結果になりました。わずかなパースや陰影(後者のような「写真」画像は、人間には均一に見える部分でも、二値化してみると結構色に偏りがあったりする)で認識精度がガクッと落ちるようです。


新フィルタ

CIFilter は

CIFilter(name: filterName, withInputParameters: params)

っていう感じでフィルタ名を文字列で指定する形式なので、API Diffs とかには新規追加フィルタは表記されない(Filter Reference というドキュメントもあるけど更新が遅い)ため、次のようにビルトインフィルタ名を全部出力しておいて、

let filterNames = CIFilter.filterNamesInCategory(kCICategoryBuiltIn)
for filterName in filterNames {
    print(filterName)
}

そのあと `diff` コマンドで新規追加分を抽出する、ということを毎年 iOS がメジャーバージョンアップするたびにやっています。


で、今年はフィルタ数の変化をグラフにしてみたのですが、


f:id:shu223:20150622071620j:image:w425


ひさびさにフィルタ数がグッと増えていて、ちょっと盛り上がりを感じます。


例によってNDAによってフィルタをかけた結果のスクショ掲載は控えますが、以下に新フィルタ名47種の一覧を載せておくので、名前から効果を察していただけると。

  • CIAreaAverage
  • CIAreaMaximum
  • CIAreaMaximumAlpha
  • CIAreaMinimum
  • CIAreaMinimumAlpha
  • CIBoxBlur
  • CICircularWrap
  • CICMYKHalftone
  • CIColumnAverage
  • CIComicEffect
  • CIConvolution7X7
  • CICrystallize
  • CIDepthOfField
  • CIDiscBlur
  • CIDisplacementDistortion
  • CIDroste
  • CIEdges
  • CIEdgeWork
  • CIGlassLozenge
  • CIHeightFieldFromMask
  • CIHexagonalPixellate
  • CIKaleidoscope
  • CILenticularHaloGenerator
  • CILineOverlay
  • CIMedianFilter
  • CIMotionBlur
  • CINoiseReduction
  • CIOpTile
  • CIPageCurlTransition
  • CIPageCurlWithShadowTransition
  • CIParallelogramTile
  • CIPDF417BarcodeGenerator
  • CIPointillize
  • CIRippleTransition
  • CIRowAverage
  • CIShadedMaterial
  • CISpotColor
  • CISpotLight
  • CIStretchCrop
  • CISunbeamsGenerator
  • CITorusLensDistortion
  • CITriangleTile
  • CIZoomBlur

会場ではシミュレータでデモしたのですが、GPUが効くので、実機でやるとチョッパヤです。



ちなみにちょっと余談ですが、会場で Yahoo の佐野さんから飛び出した「Apple は何のためにそんなにがんばってフィルタを追加しているのか?」という質問が印象的でした。


確かに、CIDetector 系は実用的だし、ボックスブラーとかノイズリダクションとか、色のブレンド系etcは写真加工系に幅広く使えそうなのでわかるとしても、CICrystallize とかの飛び道具系って実際には使う人いなそうだなぁと。そして僕はそういえば案件で Core Image 使ったことなんて記憶に無いのになぜ毎年やってるのだろう、と・・・


おわりに

他の発表者のみなさんもかぶりがないように幅広い内容で発表されていて、人数もちょうどよく和やかな雰囲気で質疑応答も盛り上がり、大変有意義な時間を過ごさせていただきました。主催のグノシーさん、発表者・参加者のみなさまどうもありがとうございました!


次回は「WWDC2015報告共有会@ネクスト」にて、Audio Unit Extensions について話させていただく予定です。


*1:参加者は Apple Developer アカウントを持っている人のみ

2015-06-17

UI/UX に影響の大きい watchOS 2 の新機能 3つ #uicrunch

本日開催された、『UI Crunch #5 スマートウォッチUIデザインの今』というイベントで、標題の発表をしてきました。



イベントタイトルからも察していただけるかもしれませんが、今回は勝手知ったる「iOSエンジニアの技術勉強会」ではなく、デザイナーさんやディレクターさんも集まる会なので、発表内容は相当に迷いました。タイミングとしてWWDC直後なので、そこで発表されたことについて話そう、ということだけは決めてはいたものの、具体的な実装の話をしてもポカーンとしてしまう方も多いだろうし、新機能をつらつら紹介しても退屈だろうし。。


というわけで、数ある新機能の中から、特に Apple Watch アプリの UI/UX にインパクトが大きいであろう(と僕は考えている)機能3つを抜粋して紹介しました。


具体的には以下の3つ。各内容についてはスライドをご覧いただければと。

  1. Complication (ClockKit)
  2. Watch Connectivity
  3. センサへのアクセス


他の登壇者の方々はがっつりつくりこんだウォッチアプリの話や、UIの考え方の話をされていて、非常に勉強になりました。お誘いいただいた主催のグッドパッチさん、DeNA さん、発表者・参加者のみなさまどうもありがとうございました!


2015-06-16

watchOS 2 新機能の細かい話5つ #potatotips

本日、potatotips #18 という iOS / Android の開発Tips共有会(勉強会)で標題の発表をしてきました。



概要

つい先日ブログに書いた、watchOS 2 のサンプルコード集「watchOS-2-Sampler」


f:id:shu223:20150614131615j:image:w200


を実装するにあたって、気付いた注意点や、調べてみてわかったこと等、本当に細かい話の寄せ集めです。


その「細かい話」の内訳は以下の通り。

1. 2つのアセットカタログの 使い分け

watchOS 2 でも、Watch Extension と App Extension それぞれに Assets.xcassets が生成されますが、ネイティブだったらどっちもウォッチ側にあるんだからどっちに置いてもよかったりするの?という話。(結論としては、ダメです)


2. メディアデータの 保存場所

presentAudioRecordingController〜 で表示されるマイク録音UIに渡す、オーディオデータの出力先の話。


3. WKAudioFilePlayer

WKAudioFilePlayer が期待したものとちょっと違った、という話と、実装の注意点。


4. ウォッチ側 Bluetooth の (直接)利用

Core Bluetooth は使って、ウォッチ側の BLE を直接的に利用できるのか?という話。


5. Watch Connectivity のメッセージ送信可否の条件

WCSession を利用した、Phone - Watch 間の相互メッセージ送信の Reachablity の話


おわりに

そもそも先週のWWDCで発表されたてホヤホヤの機能ばかりなので、「細かい話」をいきなりするよりも、その機能自体の紹介や、実装方法を紹介した方がいいかともは思ったのですが、それぞれの機能の実装方法自体はサンプルコードの通りなのと、NDAの都合でスクショやデモを見せられないので、こういう形をとりました。


いずれも単体で記事を書くほどのことではないものの、同じように疑問に思っている人やハマる人はいると思うので、こうしてまとめて発表できる機会があってよかったです。


主催の BizReach さん、発表者・参加者のみなさまどうもありがとうございました!


2015-06-14

watchOS 2 の新機能のサンプルコード集『watchOS-2-Sampler』を公開しました

先週の WWDC15 にて watchOS 2 が発表され、ついに待望のネイティブ動作する Apple Watch アプリがつくれるようになりました。それに伴い、WatchKit には多くの機能が追加され、ClockKit や WatchConnectivity 等の新しいフレームワークも登場しました。さらにいえば、従来フレームワークもウォッチ側で動作するようになったことから、これらもある意味新APIであるといえます。*1


そんなわけで、数が少なすぎてびっくりした 初代 watchOS の発表時とは打って変わって、今回は遥かに多くの「新機能」があります。どんな機能が追加されたのかは既に多くのキーノートのまとめ記事などで紹介されてはいますが、新しいAPIはどう使うのか、実際に何がどこまでできるのか、快適に動作するのか、といった具体的なところが、英語のドキュメントや動画や記事をながめているだけだと正直あまりよくわかりません。やはり実際にコード書いて動かしてみるのが一番わかりやすい、ということで、


watchOS 2 の新機能のサンプルコード集『watchOS-2-Sampler


をつくりました。オープンソースなのでどなたでも GitHub から clone してお試しいただけます。


このアプリで、とあるアメリカのハッカソンにて賞をいただきました!それについては最後に。


Contents

今のところ15個のサンプルが入っています。まだまだ少ないですが、随時追加していく予定です。あと今回から Swift で書いています。機能追加のプルリク大歓迎です!


アイコンデザインはいつものように okazu 氏にお願いしました!


f:id:shu223:20150614131615j:image:w242



各サンプルのスクリーンショットはAppleの正式リリースまで控えます。代替として、WWDCの動画などAppleによる公開資料からの画像を一部用いています)

Accelerometer

Core Motion を用いて加速度センサの値を取得するサンプル。


Gyroscope

Core Motion を用いてジャイロスコープの値を取得するサンプル。


Pedometer

CMPedometer を用いて歩数や距離、階の昇り降り情報を取得するサンプル。


Heart Rate

HealthKit を用いて心拍数を取得するサンプル。


Table Animations

WKInterfaceTable のセル(row)をアニメーション付きで insert / remove するサンプル。`insertRowsAtIndexes:withRowType:`, `removeRowsAtIndexes:` メソッドを利用。


Animated Properties

`animateWithDuration:animations:` メソッドを利用して、アニメーションで拡大縮小やフェードイン/アウト、移動(実際には Alignment)を行うサンプル。


Audio Rec & Play

`presentAudioRecordingControllerWithOutputURL:preset:maximumDuration:actionTitle:completion:` メソッドを利用して音声を録音する UI を表示し、


f:id:shu223:20150614134536j:image:w400

(WWDCのセッション動画より)

録音したファイルを `presentMediaPlayerControllerWithURL:options:completion:` メソッドを利用して再生するサンプル。


f:id:shu223:20150614134537j:image:w400

(WWDCのセッション動画より)


参考記事:watchOS 2 のオーディオ録音、再生機能を利用する - Qiita


Picker Styles

WKInterfacePicker の全スタイル(List, Sequence, Stack)を試せるサンプル。


f:id:shu223:20150614163013j:image:w600

(WWDCのセッションスライドより)


Taptic Engine

WKInterfaceDevice の `playHaptic` メソッドに指定できる全タイプ(WKHapticType)を試せるサンプル。


ちなみに WKHapticType は次のように定義されています。


enum WKHapticType : Int {
    
    case Notification
    case DirectionUp
    case DirectionDown
    case Success
    case Failure
    case Retry
    case Start
    case Stop
    case Click
}

Alert

`presentAlertControllerWithTitle:message:preferredStyle:actions:` メソッドで指定できる全アラートスタイル(WKAlertControllerStyle)を試せるサンプル。


ちなみに WKAlertControllerStyle は次のように定義されています。


enum WKAlertControllerStyle : Int {
    
    case Alert
    case SideBySideButtonsAlert
    case ActionSheet
}

Animation with Digital Crown

デジタルクラウンの回転に合わせ、WKInterfacePicker にセットしたアニメーションを表示するサンプル。`setCoordinatedAnimations` メソッドを利用。


f:id:shu223:20150614134538j:image:w350

(WWDCのセッションスライドより)


Interactive Messaging

iPhone と Apple Watch で相互にメッセージをやりとりするサンプル。Watch Connectivity フレームワークを利用。


f:id:shu223:20150616165131j:image:w350


Open System URL

WKExtension の `openSystemURL:` メソッドを利用して、電話およびSMSアプリを開くサンプル。


Audio File Player

WKAudioFilePlayer を利用してオーディオファイルを再生するサンプル。


参考記事:watchOS 2 のオーディオ録音、再生機能を利用する - Qiita


Network Access

NSURLSession を用いてネットワーク経由で画像データを取得するサンプル。KAMEDAkyosuke さんより pull request いただきました。


Known Issues

ハッカソンでガッと仕上げたこともあり、既に入っているサンプルも以下の点がまだ未完成です。

  • Audio Rec & Play
    • 実機での録音ができない。シミュレータでは可
    • 録音音声をshared containerに保存する必要がある。そうするとOSSとして試すハードルが上がってしまうのが悩みどころ。。
  • HeartRate
    • 完全に未完成。いつかやります
  • Open System URL
    • Phoneを押しても電話アプリが起動しない
    • ドキュメント通りにやってるつもりだけど・・・?
    • `sms:` は同様のやり方で動作している

あと、ジャイロは実機でもとれてませんが、実装は正しいと思ってるので一応サンプルとしては成立してるのかなと(実装間違ってたらプルリクください!)


ClockKit、WatchConnectivity は試してサンプルを入れる予定です。(2015.6.16追記:Watch Connectivity はひとつ追加しましたが、引き続きファイル送信等も試して追加する予定)


サンフランシスコで開催された  Watch Hackathon で入賞しました!

WWDC会期中にドキュメント読みつつちまちまサンプル実装はしてたのですが、WWDC終了直後の週末に Apple Watch のハッカソン がタイミングよくサンフランシスコで開催されていたので、そこでいったん仕上げて GitHub で公開し、緊張しつつ英語でプレゼンしたところ・・・なんと!賞をいただいてしまいました!!!!


f:id:shu223:20150614131616j:image:w320


コミュニティへの貢献を評価していただけたようです。英語力はプレゼンター随一の下手さだったと思いますが、ちゃんと伝わったようで、プレゼン直後、いろんな人が寄ってきてくれて「あんた、ナイスだ!」「7、8の頃から見てるよ、会えて嬉しいよ」みたいなことを言っていただけたのがとても嬉しかったです。



こんなときの挨拶用にと iOS Sampler ステッカーをつくって持っていったのが役立ちました。


f:id:shu223:20150614131617j:image:w320


あと少し残ってるので、欲しい方はお声がけください!(iOS 9 が出るまでしか使えないデザインなのでw)


関連記事:


FAQ: iOS-9-Sampler も出すの?

今回はたまたまハッカソンがあったのと、watchOS 2 のサンプルは基本的なものが多いので、早く出すことにこそ意味があるだろう、ということで即時公開しましたが、iOS-9-Sampler はいつも通り正式リリースに合わせて公開する予定です。




そんなわけで、引き続き watchOS-2-Sampler をよろしくお願いします!



こちらもどうぞ


*1:たとえば watchOS 1 から WatchKit Extension では Core Motion は使えましたが、それは単にiPhone側の機能を利用するだけのものなので「新機能」であるとはいえません。が、watchOS 2 ではウォッチ側で動作するようになったので、watchOS にとっては「新機能」です。実際、WWDC 以降、iOS Developer Library とは別に watchOS Developer Library がオープンし、watchOS 側で利用できるフレームワーク群のドキュメント類が別途管理されるようになっています。(Mac。には以前からあった Core Image が、iOS では 5 から新機能として加わった、みたいなもの。・・・というたとえは余計わかりにくいでしょうか・・・?)

2009 | 08 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 |