Exemplo n.º 1
0
 template<typename F> void subinit(F f,size_t i) {
     new(begin() + i) T(f(i));
     
     if(i < Size-1) {
         try {
             subinit(f,i+1);
         } catch(...) {
             (*this)[i].~T();
             throw;
         }
     }
 }
Exemplo n.º 2
0
// --------------------------------------------------------------------- init --
int SPECTACLE2_BASE::init(double p[], int n_args)
{
	_nargs = n_args;
#ifdef NOTYET
	_print_stats = Option::printStats();
#else
	_print_stats = true;
#endif

	if (getargs(p, n_args) < 0)	// subclass gets args
		return DONT_SCHEDULE;

	// NB: subclass init will have already grabbed all pfields except these...
	const float outskip = p[0];
	const float inskip = p[1];
	_inputdur = p[2];
	_oamp = p[3];

	// Make sure FFT length is a power of 2 <= kMaxFFTLen.
	bool valid = false;
	for (int x = 1; x <= kMaxFFTLen; x *= 2) {
		if (_fftlen == x) {
			valid = true;
			break;
		}
	}
	if (!valid)
		return die(instname(), "FFT length must be a power of two <= %d",
		                                                       kMaxFFTLen);

	_half_fftlen = _fftlen / 2;
	_fund_anal_freq = SR / float(_fftlen);

	// Make sure window length is a power of 2 >= FFT length.
	valid = false;
	for (int x = _fftlen; x <= kMaxWindowLen; x *= 2) {
		if (_window_len == x) {
			valid = true;
			break;
		}
	}
	if (!valid)
		return die(instname(),
		           "Window length must be a power of two >= FFT length (%d)\n"
		           "and <= %d.", _fftlen, kMaxWindowLen);

	// Make sure _overlap is a power of 2 in allowed range.
	valid = false;
	for (int x = kMinOverlap; x <= kMaxOverlap; x *= 2) {
		if (_overlap == x) {
			valid = true;
			break;
		}
	}
	if (!valid)
		return die(instname(),
		           "Overlap must be a power of two between %d and %d.",
		           kMinOverlap, kMaxOverlap);

	// derive decimation from overlap
	_decimation = int(_fftlen / _overlap);

	// create this now, because subinit will need it
	_bin_groups = new int [_half_fftlen + 1];

	// subclass init -- must follow FFT and bin groups init; sets _ringdur
	if (subinit(p, n_args) < 0)
		return DONT_SCHEDULE;

	if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;
	if (_inchan >= inputChannels())
		return die(instname(), "You asked for channel %d of a %d-channel input.",
		                       _inchan, inputChannels());

	// Latency is the delay before the FFT looks at actual input rather than
	// zero-padding.	Need to let inst run long enough to compensate for this,
	// as well as to span the user's requested ring-down duration.

	_window_len_minus_decimation = _window_len - _decimation;
	_latency = _window_len_minus_decimation;
	const float latency_dur = _latency / SR;
	if (rtsetoutput(outskip, latency_dur + _inputdur + _ringdur, this) == -1)
		return DONT_SCHEDULE;
	_input_frames = int(_inputdur * SR + 0.5);	// without latency_dur
	_input_end_frame = _input_frames + _latency;

	DPRINT2("_fftlen=%d, _decimation=%d\n", _fftlen, _decimation);
	DPRINT3("_latency=%d, _input_frames=%d, ring frames = %d\n",
		_latency, _input_frames, int(_ringdur * SR + 0.5));

	return nSamps();
}
Exemplo n.º 3
0
 template<typename F> init_array(size_t size,F f) {
     assert(size == Size);
     subinit(f,0);
 }