2011-12-15 9 views
1

iOSのCoreMIDI接続は、単純なオブジェクト作成とNSLogを実行している場合は、それに当たる何かを処理するのに十分なほど高速です。 UIの中には、入ってくるすべてのものを処理する時間がありません。UIが爆発したり、処理が遅すぎたりします。Objective-CでCoreMIDIを調整する方法

しかし、私はCoreMIDI入力に応じて実際の処理とUI表示を行う必要があります。私が望むのは、最新ののメッセージをすべて、例えば1msまたは2msのように処理することです。私は1ミリ秒ごとにタイマ起動メソッドによって空になるコレクションでこれを行ってきました(processFromServerAsync)。

NSDictionary *queueCopy = [self.queue copy]; 
// here the dictionary could get messages not in the queue copy! 
self.queue = [NSMutableDictionary dictionary]; 

私は台無しにするのは簡単ですロック、と同期することで、これを扱うことができることを実現:一つの問題は、私はつかむと代替ならば、私が思うに、いくつかのメッセージが割れて落ちるかもしれないということです

-(NSMutableDictionary *)messageQueue { 
    @synchronized(self) { 
     if (!messageQueue_) 
      self.messageQueue = [NSMutableDictionary dictionary]; 
     return messageQueue_; 
    } 
} 

-(NSDictionary*)clearMessageQueueAndReturnCopy { 
    @synchronized(self) { 
     if (!messageQueue_) 
      return [NSDictionary dictionary]; 
     NSDictionary *retVal = [messageQueue_ copy]; 
     self.messageQueue = [NSMutableDictionary dictionary]; 
     return retVal; 
    } 
} 

しかし、私はこれを正しい方法で処理しているとは確信していません。 (Obj-Cの外でも)調整はどのように一般的に行われますか? UIやプログラムでこれらのメッセージをすべて処理することはできません。

+0

なぜこれほど多くのメッセージ?クロック?あなたはできるだけ早くあなたが外部MIDIハードウェア上でできるように4つのスライダをスライドさせた場合 –

+0

@TimKempは、それはCoreMIDIのためにあまりにも多くはないが、それは、任意の論理処理を行うにはLOTです。すごく準備ができています。 –

+0

私はあなたを得ました、それは多くのデータです。 –

答えて

1

受信データのストリームを抑制するためのいくつかのよく確立されたパターンがあります。これは、システムで100Kメッセージ/秒を投げているデータフィードを持っている可能性のある、財務面で大いに役立ちます。

スライディングウィンドウメカニズムを使用して、冗長メッセージを破棄し、クライアントに最新のデータコピーがあることを保証します。あなたは、最初のメッセージが入るときは、グローバルタイマーを起動し、その後(特にCC、MIDIノートなどを意味する)各データストリームのためのキューを設定いくつかの時間(数ミリ秒)の上にウィンドウを設定します。あなたはそのメッセージを送信しますすぐにクライアントに送信します。ウィンドウ内で何か他のものが入ってくると、それをそのキューにプッシュします。キューには1つのエントリ(最新の値)しかないため、キューに入れられた値はその後の各更新で上書きされます。タイマーが刻々と変化する(ウィンドウが終了する)と、最新のメッセージをクライアントに送信します。次に、次のメッセージをすぐに送信し、新しいウィンドウを開き、繰り返します。これは、クライアントを急上昇させることと、タイマーウィンドウに対する更新間隔のエイリアシングを回避することとの間で、妥当なバランスを提供する。エイリアシングは1〜2ms間隔の問題ではありませんので、より厳しいタイマー方式が有効です。

重要なことは、データストリームごとに別々のウィンドウを用意することです。コントロールの変更が入ったため、ノートを上書きしたり無視したりする危険性はありません。1つのタイマー、Midiメッセージ番号ごとに1つの単一エントリキュー。

+0

したがって、財務の例では、株価記号ごとに1つのデータストリームがあります。そして、あなたはデータストリームのように多くのタイマーを実行していますか?また、今私は私が処理が完了していた場合にのみ再スケジューリングであることを処理する必要が推測...私の処理が割り当てられた時間内に終えることができないことを心配.... –

+1

それは実際にシンボル毎に属性ごとに1つのストリームの、例えばボーダフォンビッド、ボーダフォンオファーは2つのストリームです。コンフリクトはしばしば画面用ですので、250〜500msのウィンドウを使用しています。私は答えを編集しました。なぜなら、1つの共有タイマーを使用することは明らかではないからです。 「ストリーム」は、その特定のデータムの最新のコピーを保持するだけのシングルエントリキューに似ています。 –

+0

うーん...ここだけのウィンドウを忘れると、できるだけ早く再スケジュール何、ウィンドウサイズがはるかに小さいと、処理時間は、ウィンドウサイズを超える可能性があり、そう...? –

関連する問題