diff --git a/jconvolver-0.8.4/source/jclient.cc b/jconvolver-0.8.4/source/jclient.cc index 5feb421..c57bd71 100644 --- a/jconvolver-0.8.4/source/jclient.cc +++ b/jconvolver-0.8.4/source/jclient.cc @@ -30,7 +30,8 @@ Jclient::Jclient (const char *name, Convproc *conv) : _mode (PM_CONVOL), _ninp (0), _nout (0), - _conv (conv) + _conv (conv), + _fweel (0) { init_jack (); } @@ -138,10 +139,16 @@ void Jclient::jack_static_shutdown (void *arg) void Jclient::jack_static_freewheel (int state, void *arg) { + Jclient *me = (Jclient *) arg; if (state) { - fprintf (stderr, "WARNING: jconvolver may not work correctly in freewheel mode.\n"); + if( me->_conv ) + me->_conv->drop_rt (); + } else { + if( me->_conv ) + me->_conv->get_rt (); } + me->_fweel = state ? true : false; } @@ -224,7 +231,7 @@ void Jclient::jack_process (void) } } - _conv->process (); + _conv->process ( false, _fweel ); for (i = 0; i < _nout; i++) { diff --git a/jconvolver-0.8.4/source/jclient.h b/jconvolver-0.8.4/source/jclient.h index 80240d0..998e188 100644 --- a/jconvolver-0.8.4/source/jclient.h +++ b/jconvolver-0.8.4/source/jclient.h @@ -69,6 +69,8 @@ private: unsigned int _ninp; unsigned int _nout; Convproc *_conv; + bool _fweel; + static void jack_static_shutdown (void *arg); static void jack_static_freewheel (int state, void *arg); diff --git a/zita-convolver-2.0.0/libs/zita-convolver.cc b/zita-convolver-2.0.0/libs/zita-convolver.cc index 9cb45ad..96fe319 100644 --- a/zita-convolver-2.0.0/libs/zita-convolver.cc +++ b/zita-convolver-2.0.0/libs/zita-convolver.cc @@ -282,7 +282,7 @@ int Convproc::cleanup (void) } -void Convproc::process (bool skip) +void Convproc::process (bool skip, bool sync) { unsigned int f, k; @@ -296,7 +296,7 @@ void Convproc::process (bool skip) { _outoffs = f = 0; for (k = 0; k < _nout; k++) memset (_outbuff [k], 0, _minpart * sizeof (float)); - for (k = 0; k < _nproc; k++) f |= _procs [k].readout (skip); + for (k = 0; k < _nproc; k++) f |= _procs [k].readout (skip, sync); if (f) { _flags |= f; @@ -327,7 +327,21 @@ void Convproc::print (void) for (k = 0; k < _nproc; k++) _procs [k].print (); } +int Convproc::get_rt () +{ + unsigned int k; + int f=0; + for (k = 0; k < _nproc; k++) f |= _procs [k].get_rt (); + return f; +} +int Convproc::drop_rt () +{ + unsigned int k; + int f=0; + for (k = 0; k < _nproc; k++) f |= _procs [k].drop_rt (); + return f; +} typedef float FV4 __attribute__ ((vector_size(16))); @@ -338,6 +352,7 @@ Convlevel::Convlevel (void) : _parsize (0), _vectopt (0), _pthr (0), + _done_count (0), _inp_list (0), _out_list (0), _plan_r2c (0), @@ -346,6 +361,8 @@ Convlevel::Convlevel (void) : _prep_data (0), _freq_data (0) { + pthread_mutex_init (&_sync_lock, NULL); + pthread_cond_init (&_done, NULL); } @@ -551,10 +568,10 @@ void Convlevel::start (int priority, int schclass) _pthr = 0; min = sched_get_priority_min (schclass); max = sched_get_priority_max (schclass); - priority += _prio; - if (priority > max) priority = max; - if (priority < min) priority = min; - parm.sched_priority = priority; + _priority = priority + _prio; + if (_priority > max) _priority = max; + if (_priority < min) _priority = min; + parm.sched_priority = _priority; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setschedpolicy (&attr, schclass); @@ -566,6 +583,37 @@ void Convlevel::start (int priority, int schclass) pthread_attr_destroy (&attr); } +int Convlevel::drop_rt () +{ + struct sched_param rtparam; + + if (_stat != ST_PROC) + return 0; + + memset (&rtparam, 0, sizeof (rtparam)); + rtparam.sched_priority = 0; + + if (pthread_setschedparam (_pthr, SCHED_OTHER, &rtparam) != 0) { + return -1; + } + return 0; +} + +int Convlevel::get_rt () +{ + struct sched_param rtparam; + + if (_stat != ST_PROC) + return 0; + + memset (&rtparam, 0, sizeof (rtparam)); + rtparam.sched_priority = _priority; + + if (pthread_setschedparam (_pthr, SCHED_FIFO, &rtparam) != 0) { + return -1; + } + return 0; +} void Convlevel::stop (void) { @@ -646,6 +694,7 @@ void Convlevel::main (void) while (true) { sem_wait (&_trig); + if (_stat == ST_TERM) { _stat = ST_IDLE; @@ -653,6 +702,11 @@ void Convlevel::main (void) return; } process (false); + + pthread_mutex_lock (&_sync_lock); + _done_count += 1; + pthread_cond_signal (&_done); + pthread_mutex_unlock (&_sync_lock); } } @@ -764,7 +818,7 @@ void Convlevel::process (bool skip) } -int Convlevel::readout (bool skip) +int Convlevel::readout (bool skip, bool sync) { unsigned int k; Outnode *Y; @@ -774,8 +828,27 @@ int Convlevel::readout (bool skip) if (_outoffs == _parsize) { _outoffs = 0; + + if (_stat == ST_PROC) { + if (sync) + { + pthread_mutex_lock (&_sync_lock); + while (_done_count < 0) + pthread_cond_wait (&_done, &_sync_lock); + _done_count -= 1; + pthread_mutex_unlock (&_sync_lock); + } else { + // this lock/unlock could be removed if the counter was atomic + // however atomic stuff is not really portable. and if the other thread + // holds this lock at this point, we could consider it late anyways. + // it doesnt do much while holding it. so this is probably better. + pthread_mutex_lock (&_sync_lock); + _done_count -= 1; + pthread_mutex_unlock (&_sync_lock); + } + k = _opi1; _opi1 = _opi2; _opi2 = _opi3; diff --git a/zita-convolver-2.0.0/libs/zita-convolver.h b/zita-convolver-2.0.0/libs/zita-convolver.h index cbc1e54..b069dbd 100644 --- a/zita-convolver-2.0.0/libs/zita-convolver.h +++ b/zita-convolver-2.0.0/libs/zita-convolver.h @@ -125,10 +125,12 @@ private: unsigned int out2); void reset (void); void cleanup (void); - int readout (bool skip); + int readout (bool skip, bool sync); void fftswap (fftwf_complex *p); bool idle (void) const { return _stat == ST_IDLE; } void print (void); + int get_rt(); + int drop_rt(); static void *static_main (void *arg); void main (void); @@ -138,6 +140,7 @@ private: volatile unsigned int _stat; // current processing state int _prio; // relative priority + int _priority; // absolute priority unsigned int _offs; // offset from start of impulse response unsigned int _npar; // number of partitions unsigned int _parsize; // partition and outbut buffer size @@ -154,6 +157,9 @@ private: int _late; pthread_t _pthr; sem_t _trig; + pthread_mutex_t _sync_lock; + pthread_cond_t _done; + volatile int _done_count; Inpnode *_inp_list; Outnode *_out_list; @@ -269,7 +275,11 @@ public: void print (void); - void process (bool skip = false); + void process (bool skip = false, bool sync = false); + + int get_rt(); + int drop_rt(); + private: