PWM-1のMIDI対応のお話

昨日、慌ててMIDI対応してリリースしたんだけど、
IAAホストアプリにホストされている時の挙動が怪しかったので、
引き続き調査してみた。

何が問題だったかというと、
MIDIデバイスの接続/解除を検知すると、
自動で接続/解除を行うようにしていたんだけど、それが裏目に出た。
正確には、IAAにホストされてるときに検知しても、
アプリが裏に回ってる時はUIを更新してはいけない。

もう少し具体的に。

MIDIの初期化は、
iOS9.0から使えるMIDIClientCreateWithBlockを使ってるんだけど、
3つ目の引数で検知した時のコールバックをブロック(クロージャ?)で渡せる。

    // どこぞの関数の中で初期化
    //var status: OSStatus = noErr
    //status = MIDIClientCreateWithBlock( self.midiInstName, &self.clientRef, MyMIDINotifyBlock )
    //if status != noErr {
    //    print( "MIDIClientCreateWithBlock failed. \(status)" )
    //    return
    //}

    func MyMIDINotifyBlock(midiNotification: UnsafePointer<MIDINotification>) {
        switch midiNotification.memory.messageID {
        case .MsgObjectAdded:
            break // 接続を検知
        case .MsgObjectRemoved:
            break // 解除を検知
        case .MsgIOError:
            break // エラーを検知
        default:
            break
        }
    }

PWM-1だと、viewDidLoadで初期化して、deinitで解放してる。
もちろん、MIDIClientCreateWithBlockのあとに、
MIDIInputPortCreateを呼んでるんだけど、
後者は、MIDIPacketを処理する都合上、ObjC側で呼び出している。

まずは、MIDIClientCreateWithBlockだけど、
PWM-1では、UIの更新をどうしたかというと、

    // MyMIDINotifyBlockの中では、こんな感じでチェックする
    if UIApplication.sharedApplication().applicationState == .Active {
        // todo: UIを更新
    }

上記とは別に、

    //NSNotificationCenter.defaultCenter().addObserver(
    //    self,
    //    selector: #selector(ViewController.appWillEnterForeground(_:)),
    //    name: UIApplicationWillEnterForegroundNotification, object: nil )

    func appWillEnterForeground(notification: NSNotification?) {
        // todo: UIを更新
    }

ついでに言うと、viewDidLoadの中からも、
appWillEnterForeground( nil )って書いて呼び出してる。
viewDidLoadの中でなら、UIにアクセスしても良いらしい。
IAAアプリによってPWM-1が起動した場合も、
viewDidLoadが呼ばれるが、UIを初期化しても大丈夫だった。

最後に、MIDIPacketだけど、
Swiftだと、配列だったメンバ変数がタプルに置き換えられてて、
これはどうにもならないなってことで、
最初はMIDIPacketをObjCに渡して処理してたけど、
まるっとObjC側でコールバックを登録して処理することにした。

シーケンサーみたいなアプリの場合、
いまどの辺りを鳴らしてるか表示するのに困るかも知れないけど、
とりあえず、PWM-1ではそれをしないので良しとした。

こんな文章じゃ良く分かんないよーって人は、
直接会って聞いていただければと思う。

おしまい。

Leave a Comment