サウンド処理アプリケーションでは、多くのイベントは、このシナリオでは壁時間と呼ばれるシステム時間ではなく、オーディオ ストリーム時間 (最初の概算では、消費されたサンプルの数に係数を掛けたもの) から時間を計られます。たとえば、ストリーム時間に基づいて将来のイベントの時間を計るのが望ましい場合がよくあります。たとえば、一定時間音声アクティビティがなかった場合に録音を受け入れるようにタイマーをスケジュールできます。この目的では、実時間よりもストリーム時間の方が時間を表すのに適しています。
HistoricalScheduler
そのような活動のタイミングに を使用することを考えています。私が理解している限り、それはすべてのスケジュールされたアクションを呼び出した同じスレッドで実行しますAdvanceBy/To
。また、少なくとも RX を使用するようなサードパーティの部分がないという意味で、アプリケーション全体が私たちの管理下にあります。
質問 1:この考えは正しいですか、大丈夫ですか、それとも信じられないほどばかげていますか? 私はRXを頭で理解していますが、経験はありません。必要に応じて直感で理解してください。
ストリームは、.NET イベント コールバックを通じて配信されます。ストリーム バッファを配信する (およびイベントを呼び出す) スレッドは、できるだけブロックしないようにする必要があります。オーディオは有限長のエンドレス バッファに転送されます。この実際のバッファリングは、専用スレッドで監視しているこのイベントのオブザーバで発生し、ここでスケジューラの時間が進みます。基本的に、これは次のようになります
IDisposable _sub;
// The historic scheduler that reflects the time of
// the last sample in the endless buffer.
HistoricalScheduler _hisch = new HistoricalScheduler();
// This must be disposed of.
EventLoopScheduler _eventLoopSch = new EventLoopScheduler();
public IScheduler StreamTimeScheduler => _hisch;
// Subscribing to the stream.
void Initialize() {
_sub = Observable.FromEventPattern<TEventHandler, TEventArgs>(
h => ReceivedAudio += h,
h => ReceivedAudio -= h)
.ObserveOn(_eventLoopSch)
.Subscribe(b => Append(b));
}
// The function that puts samples into the endless buffer.
void Append(byte[] sample) {
// ...put the sample into the array...
_hisch.AdvanceBy(TimeSpan.FromSeconds(sample.Length / _avgBytesPerSecond));
}
質問 2:上記の例のように、監視関数内からスケジューラを進めるのは奇妙に感じます。これは容認できる慣行ですか、それともすぐに怪しいにおいがしますか (または、両極端の中間にあるのでしょうか)。
もう 1 つの複雑な問題は、ストリームが最終的にデータの生成を停止し、ストリーム時間も停止することです。
質問 3:一部のスケジュールされたアクションが決して実行されず、永久にキューに残るように、スケジューラーで時間を停止することの影響はありますか? スケジューラへの参照を削除するだけで、使い捨てのリソース リークが発生しますか?
また、ストリーミング時間は実時間とは異なります。
質問 4:一貫性のない概念を提供するさまざまなスケジューラの影響は、あるとすれば何Now
ですか?
他のシナリオではリアルタイムスケジューラと平和的に共存するため、ここでの私の最善の推測は「まったくない」ですがHistoricScheduler
、RXのこの部分を十分に理解しているかどうかはわかりません。