essentia
essentia copied to clipboard
Help needed with single shot composite steps in streaming network mode
Hi!
I've broken my mind already trying to figure out why my KeyExtractor is not working in real-time streaming mode as I want it, that is emitting predictions regularly over its buffered data.
I conclude that the reason is that there is some problem with how single-shot composite steps are (not)working.
First, this is what it looks like after several seconds of running a simple KeyExtractor network in a RingBufferInput streaming mode (calling runStep()
periodically)
[Scheduler ] ------------------------ Buffer states after running the generator and all the nodes ------------------------
[Scheduler ] RingBufferInput (called 195 times)
[Scheduler ] - signal fill 10% | 15312 / 144176 | contiguous: 18022 | total produced: 133120
[Scheduler ]
[Scheduler ] FrameCutter (called 22 times)
[Scheduler ] - frame fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
[Scheduler ]
[Scheduler ] Windowing (called 21 times)
[Scheduler ] - frame fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
[Scheduler ]
[Scheduler ] Spectrum (called 21 times)
[Scheduler ] - spectrum fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
[Scheduler ]
[Scheduler ] SpectralWhitening (called 21 times)
[Scheduler ] - magnitudes fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
[Scheduler ]
[Scheduler ] HPCP (called 21 times)
[Scheduler ] - hpcp fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
[Scheduler ]
[Scheduler ] PoolStorage (called 21 times)
[Scheduler ]
[Scheduler ] Key (called 0 times)
[Scheduler ] - key fill 0% | 0 / 16 | contiguous: 0 | total produced: 0
[Scheduler ] - scale fill 0% | 0 / 16 | contiguous: 0 | total produced: 0
[Scheduler ] - strength fill 0% | 0 / 16 | contiguous: 0 | total produced: 0
[Scheduler ]
[Scheduler ] DevNull<Real>[0] (called 0 times)
[Scheduler ]
[Scheduler ] DevNull<std::string>[1] (called 0 times)
[Scheduler ]
[Scheduler ] DevNull<std::string>[0] (called 0 times)
[Scheduler ]
[Scheduler ] SpectralPeaks (called 21 times)
[Scheduler ] - frequencies fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
[Scheduler ] - magnitudes fill 0% | 0 / 16 | contiguous: 0 | total produced: 21
One can clearly see that data is being fed to the PoolStorage step of the Key streaming composite, but the recursive Key step is never executed.
Just for reference, this is how Key is defined
void declareProcessOrder() {
declareProcessStep(SingleShot(_poolStorage));
declareProcessStep(SingleShot(this));
}
The self-referencing magic of such recursive Composite Algo is fully dependent on the following code:
AlgorithmStatus Key::process() {
if (!shouldStop()) return PASS;
const vector<vector<Real> >& hpcpKey = _pool.value<vector<vector<Real> > >("internal.hpcp");
vector<Real> hpcpAverage = meanFrames(hpcpKey);
....
Here, the key concept is around the shouldStop()
call, which is used to decide whether to finally process accumulated data in the pool or wait for more.
My biggest issue is:
shouldStop()
never returns true for a RingBufferInput
More than that, if I would accept the fact and construct a whole network, running it periodically with a pre-aggregated sample vector input, then what's the whole point of making a streaming version of the Key algorithm???
oof...
When I proceed thinking about it, I kind of don't see how "single shot" is otherwise different from a "chain" composite step? Without any special logic to simulate local finished network run it looks like I could add a single shot step as a chain step with just one algo. It would just be executed as other chain members.
If the only reason for a single shot step is to make it possible to recursively reference self, then the whole resulting effect doesn't look any different from an Aggregator algorithm. That one acts the same: silently accumulates inputs during the run and then has the chance to finalize upon generator EOF. For this encapsulation, one could just make pre-defined chains of simple algos without having to invent an internal composition semantics.
Where am I wrong?
Thanks!
Same problem here, right now seems impossible to use Essentia algorithms with realtime data. That "shouldStop" check at the beginning of the "process" function is a show-stopper here.
Any recent movement on this front or workarounds that have been developed? I'm encountering the same issue, which leads to hangs when calling "process" and "runStep" when there isn't enough data accumulated in the buffer.