投稿

11月, 2014の投稿を表示しています

AVMIDIPlayer

iOSのAPIの中にAVMIDIPlayerというものを発見。これは音楽ファイルを再生するもので、対象フォーマットはMIDIとiMelody。iMelodyというのは着メロのような単音の音楽を扱うものらしい。所属はAVFoundationでiOS 8より追加になった。

初期化メソッドは2つ。
initWithContentsOfURL: soundBankURL: error:
initWithData: soundBankURL: error:
上のメソッドでは1つ目の引数はファイルのURLを渡し、2つ目の引数でsoundBankというもののURLを渡す。2つ目のsoundBankURLだが、これは再生に使う音源の指定でSoundFont2かDLS bank(のURL)を指定する。OS Xではnilが可能だが、iOSではnilはだめ。
下のメソッドでは1つ目の引数はNSDataインスタンス(の形式にした音楽ファイル)を渡す。2つ目以降は上のと同じ。
SoundFont2は音色のデータフォーマット。世の中でよく(?)使われている。DLSも音色のデータフォーマットだがSoundFont2の方がメジャー。

再生データ(第一引数)と音色データ(第二引数)の違いがややこしいと思う。音色データにはいろいろな音色のいろいろな音程の音が含まれている。それをどのタイミングでどの音を鳴らすかを指定するのが再生データ。

再生関係メソッドは普通に
play:
stop
prepareToPlay
playの引数で再生完了時に実行する処理を渡せる

プロパティは
playing (再生中かどうか readOnly)
duration (全体の時間 readOnly)
currentPosition (現在ポジション 読み書き可能)
そのほかに、MIDIらしく
rate (再生速度、1.0が標準 読み書き可能)
というものがある。

手持ちのMIDIファイルとダウンロードしたSoundFontで鳴らしてみたらiPad mini 2から音が出ました。まあ普通に再生出来ています。複数チャンネルにも対応しています。
しかしこうなるとiOSに初めから手頃な音源が搭載されていて欲しくなります。

SwiftのNSNumberでの符号なし整数の扱い

(追記 2015/10/22)
Xcode7.1出ました。修正されました。
リリースノートには

The NSNumberunsignedIntegerValue property now has the type UInt instead of Int, as do other methods and properties that use the NSUInteger type in Objective-C and whose names contain "unsigned..".
Most other uses of NSUInteger in system frameworks are imported as Int as they were in Xcode 7. (19134055)


と書かれています。
NSNumberは無事
public init(unsignedInteger value: UInt) public var unsignedIntegerValue: UInt { get } に変更されました。

(追記 2015/9/25)
Xcode7.1より修正されるようです。


【Xcode 6.1】
SwiftのNSNumberではUIntとなりそうなところでなぜかIntが定義されています。
具体的には初期化メソッドの
init(unsignedInteger value: Int) と値取り出しの
var unsignedIntegerValue: Int { get } です。
間違いかと思ったのですが、両方で同じように変わっているのでわざとかなという気もします。

参考までにNSNumberで扱われているその他の型がObjective-CとSwiftでどう対応しているかは

BOOL(Objective-C)
Bool(Swift)

char(Objective-C)
Int8(Swift)

double(Objective-C)
Double(Swift)

float(Objective-C)
Float(Swift)

int(Objective-C)
Int32(Swift)
どちらも32

NSInteger(Objective-C)
Int(Swift)
どちらも32環境で32、64環境で64

long long(Obje…

iOS8のTabViewControllerでのViewがLoadされるタイミング

iOS8ではViewがLoadのされるタイミングが少し変更されているようです。

以下の記事ではSegue実行時の流れを調べました。
http://samekard.blogspot.jp/2012/03/storyboard.html
この記事では次のように書きました。

1 performSegueWithIdentifier開始
2 新しいViewControllerのインスタンス化(initなど)
3 prepareForSegue開始
4 prepareForSegue終了
5 UIKitのインスタンス化、画面回転メソッドの呼び出し、viewDidLoadなど
6 performSegueWithIdentifier終了

iOS8でも移行先のViewControllerがシンプルなものであればこの通りなのですが、TabBarControllerの初めに表示されるViewControllerの場合はこのようになります。
4 prepareForSegue終了
5 performSegueWithIdentifier終了
6 UIKitのインスタンス化、画面回転メソッドの呼び出し、viewDidLoadなど
(2番目移行に表示されるViewControllerは表示の直前でViewをLoadします)

TabViewControllerに乗っている各ViewControllerのViewはperformSegueWithIdentifierより後でインスタンス化するようです。ちなみにViewController自体は2の時点でインスタンス化されます。