使用自定义调度程序进行音频流时间

时间:2016-05-04 21:33:47

标签: c# system.reactive rx.net

在声音处理应用程序中,许多事件的时间偏离音频流时间(在第一次近似中,只是消耗的样本数乘以系数),而不是系统时间,在这种情况下通常称为壁时间。例如,通常希望基于流时间对未来事件计时。例如,如果在一段时间内没有语音活动,则可以安排计时器接受录音;为了这个目的,流时间比壁钟时间更能代表时间。

我正在考虑使用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:我觉得从观察功能中推进调度程序很奇怪,如上例所示。这是一种可接受的做法,还是立即闻到腥味(或者它可能介于两个极端之间)?

另一个可能的复杂因素是流最终会停止生成数据,流时间也是如此。

问题3:在调度程序中停止时间会产生什么影响,以致某些预定的操作永远不会执行并永远保留在队列中?简单地删除对调度程序的引用会导致一次性资源泄漏吗?

流时间也与挂钟时间不同。

问题4:不同调度程序的含义是什么({1}}提供不一致的概念?

我最好的猜测是&#34;没有,&#34;因为Now在其他情况下和平时与实时调度程序共存,但我不确定我是否理解RX的这一部分也不会问这个问题。

0 个答案:

没有答案