ObjecTips

Swift & Objective-C で iOS とか macOS とか

iOS 8.3 to iOS 9.0 API Differences オーディオ周り

オーディオ周りの変更点のまとめ。いい感じに進化していってる。

関連記事は以下
iOS 8.3 to iOS 9.0 API Differences Core Image - ObjecTips
iOS 8.3 to iOS 9.0 API Differences オーディオ周り - ObjecTips
iOS 8.3 to iOS 9.0 API Differences ネットワークとWeb周り - ObjecTips
iOS 8.3 to iOS 9.0 API Differences CoreLocation - ObjecTips
iOS 8.3 to iOS 9.0 API Differences CoreTelephony - ObjecTips

AudioToolbox

AudioServices
extern void
AudioServicesPlayAlertSoundWithCompletion(  SystemSoundID inSystemSoundID,
                                            void (^__nullable inCompletionBlock)(void))
                                                                    __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0);
extern void
AudioServicesPlaySystemSoundWithCompletion(     SystemSoundID inSystemSoundID,
                                                void (^__nullable inCompletionBlock)(void))
                                                                        __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0);

システムサウンドを鳴らす関数に completion 付きのものが追加された。

AudioUnit

AUAudioUnit

AudioUnit系のAPICocoa化された。
AUAudioUnit クラスはAU自体を表していて、AVFoundation.framework の AVAudioUnitAUを保持しているクラスでオーディオの再生に関わるクラスになっている。 AVAudioUnit の方に AUAudioUnit を取得するプロパティが readonly で定義されている。

@property (nonatomic, readonly) AUAudioUnit *AUAudioUnit NS_AVAILABLE(10_11, 9_0);

iOS 8では

[[AVAudioUnitDelay alloc] init];

のようにAUをクラス指定でインスタンス化していたのがiOS 9では

+ (void)instantiateWithComponentDescription:(AudioComponentDescription)audioComponentDescription options:(AudioComponentInstantiationOptions)options completionHandler:(void (^)(__nullable __kindof AVAudioUnit *audioUnit, __nullable NSError *error))completionHandler NS_AVAILABLE(10_11, 9_0);

でパラメータを渡す事で指定の AVAudioUnitインスタンス化する事ができるようになった。

AVFoundation

AVAssetDownloadURLSession, AVAssetDownloadTask
- (nullable AVAssetDownloadTask *)assetDownloadTaskWithURLAsset:(AVURLAsset *)URLAsset destinationURL:(NSURL *)destinationURL options:(nullable NSDictionary<NSString *, id> *)options;

アセットのダウンロードする URLSession と Task が追加された。
delegate メソッド

- (void)URLSession:(NSURLSession *)session assetDownloadTask:(AVAssetDownloadTask *)assetDownloadTask didLoadTimeRange:(CMTimeRange)timeRange totalTimeRangesLoaded:(NSArray<NSValue *> *)loadedTimeRanges timeRangeExpectedToLoad:(CMTimeRange)timeRangeExpectedToLoad NS_AVAILABLE_IOS(9_0);
- (void)URLSession:(NSURLSession *)session assetDownloadTask:(AVAssetDownloadTask *)assetDownloadTask didResolveMediaSelection:(AVMediaSelection *)resolvedMediaSelection NS_AVAILABLE_IOS(9_0);

の2つがあって、
前者はデータサイズのバイト値ではなく再生時間ベースなので再生タイムラインのどこまでデータを読み込んだかのプログレス表示に使える。

AVAudioCompressedBuffer

iOS 8 では AVAudioBuffer のサブクラスとして AVAudioPCMBuffer のみが存在した。
AVAudioCompressedBuffer でPCMでない圧縮形式のオーディオフォーマットを直接扱えるようになったっぽい。

AVAudioConverter

AudioToolbox.framework の AudioConverter のCocoa

AVAudioSequencer

たぶん AudioToolbox.framework の MusicPlayer のCocoa

AVAudioUnit

以前は

@property (nonatomic, readonly) AudioUnit audioUnit;

AudioUnit を取得できたのが

@property (nonatomic, readonly) AUAudioUnit *AUAudioUnit NS_AVAILABLE(10_11, 9_0);

AUAudioUnit オブジェクトを取得できるようになった。

AVAudioUnitComponent

これもCocoa

AVCaptureMetadataInput

従来 AVCaptureMetadataOutput ってのはあって、これはカメラ撮影で顔認識やQRコードの認識をするのに使った。
その際にカメラデバイスが入力 AVCaptureDeviceInputメタデータの流れてくるのが出力 AVCaptureMetadataOutput になる。
このクラスのメタデータを入力するというのは、、もしかすると動画ファイルの書き出し(出力)の際に自由にメタデータを付与できるって事かな?

AVCaptureSession

AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps
たぶん iPad のマルチタスキングの際の話。iPad 向けのアプリではやるべき制御が増えそう、、。

AVCaptureStillImageOutput

ブラケットキャプチャ(1度のシャッターで複数枚の写真を撮るやつ)でレンズのスタビライザーを使うメソッドが追加。

@property(nonatomic, readonly, getter=isLensStabilizationDuringBracketedCaptureSupported) BOOL lensStabilizationDuringBracketedCaptureSupported NS_AVAILABLE_IOS(9_0);
@property(nonatomic, getter=isLensStabilizationDuringBracketedCaptureEnabled) BOOL lensStabilizationDuringBracketedCaptureEnabled NS_AVAILABLE_IOS(9_0);
AVFAudio.h

diffs に内容の記載がないので何だろうと思ってヘッダファイルを見てみたら、AVFoundation のクラス群を import するためのヘッダファイルだった。
AVF は AudioVisualFoundation の略だった模様。

AVPlayerLayer
@property (nonatomic, copy, nullable) NSDictionary<NSString *, id> *pixelBufferAttributes NS_AVAILABLE(10_11, 9_0);

pixel buffer の attribute を設定できるようになった。プレビュー表示の画質を落としてパフォーマンスを稼ぐとかできそう。

AVSpeechSynthesis

既存のテキストスピーチAPIはまず喋らせる文字列・ピッチ・音量などを決める AVSpeechUtterance を作成。言語を決定する AVSpeechSynthesisVoiceAVSpeechUtterance に設定。発声器である AVSpeechSynthesizerAVSpeechUtterance を渡してスピーチ開始という構成になっていた。

iOS 9ではこの AVSpeechSynthesisVoice クラスを喋り手の identifier から生成する事ができるようになった。喋り手の identifier からこのクラスを生成すると言語は自動的に決まるようになっている。
このAPIによって人物の音声を指定して発声をする事が可能になる、、と思いきや現状では en_US の AVSpeechSynthesisVoiceIdentifierAlex しか定義されていないので喋り手は Alex しか指定できない模様。まだβ1だから今後増えていくと思う。

なお AVSpeechSynthesisVoice に追加された identifier, name, quality のプロパティは全て readonly で変更する事はできない。生成した Voice のインスタンスの値を確認できるのみ。

@property(nonatomic, readonly) NSString *identifier NS_AVAILABLE_IOS(9_0);
@property(nonatomic, readonly) NSString *name NS_AVAILABLE_IOS(9_0);
@property(nonatomic, readonly) AVSpeechSynthesisVoiceQuality quality NS_AVAILABLE_IOS(9_0);

例えば voiceWithLanguage: メソッドで言語指定でボイスを生成した時以下のようになる。

language code identifier name quality
en_US com.apple.ttsbundle.Samantha-compact Samantha AVSpeechSynthesisVoiceQualityDefault
ja_JP com.apple.ttsbundle.Kyoko-compact Kyoko AVSpeechSynthesisVoiceQualityDefault

以下のコードで全ての voices を表示してみたところ全ての Voice の quiality は Default だった。

NSLog(@"%@", [AVSpeechSynthesisVoice speechVoices]);


Apple のサポートに書いてある以下
https://support.apple.com/ja-jp/HT202362

ここでダウンロード可能な「高品質」の声が AVSpeechSynthesisVoiceQualityEnhanced にあたると思われる。

AVVideoCompositing

AVAsynchronousCIImageFilteringRequest
ビデオの作成時に CIFilter でエフェクトをかけられるようになった。いいね。

AVKit

AVPictureInPictureController

ピクチャーインピクチャー用の ViewController
diffs のドキュメントでは Added -[AVPictureInPictureController cancelPictureInPicture] と記載があるけどリリースノートを見たら

The AVPictureInPictureController method cancelPictureInPicture is deprecated.

と書いてあった。
AVPictureInPictureController.h を確認すると

- (void)cancelPictureInPicture NS_DEPRECATED_IOS(9_0, 9_0);

iOS 9で available になっていて iOS 9で deprecated になっていた。
オーディオ周りってこういう事とかOSの正式リリースまでに deprecated になったりとか事ままある印象。

ついでに

@property (nonatomic, strong, nullable) AVPlayer *player NS_DEPRECATED_IOS(9_0, 9_0);

も同様に available & deprecated になっていた。

AVPlayerViewController

動画や音声の再生用の ViewController でこれ自体は iOS 8 からあるけど iOS 9で PiP 用のAPIが増えた。

CoreAudioKit

AUViewController
- (void)requestViewControllerWithCompletionHandler:(void (^)(AUViewController * __nullable viewController))completionHandler;

AUAudioUnit オブジェクトのコントロールUIを呼び出してくれるメソッド
UIの無いAUの場合 nil が返ってくる。

CoreMIDI

MIDIService

MIDIClientCreateWithBlock() MIDIDestinationCreateWithBlock() MIDIInputPortCreateWithBlock() などブロック系でコールバックを受け取れる関数が追加された。
従来のコールバック関数を登録する形のものもまだ使える。

MediaPlayer

MediaPlayer.framework 自体は生きているけど MPMoviePlayerController MPMoviePlayerViewController 再生コントローラを提供するこの2つのクラスと MPMediaPlayback プロトコルは deprecated になった。
AVKit の AVPlayerViewController にリプレイスする。