예제 #1
0
// ---------------------------------------------------------------- subupdate --
void SPECTEQ2::subupdate()
{
	// NB: update EQ table, so that live table draw will work
	double p[15];
	update(p, 15, 1 << 3 | 1 << 8 | 1 << 9 | 1 << 10 | 1 << 12 | 1 << 14);

	set_oamp(p[3]);
	set_freqrange(p[9], p[10], "EQ");
	set_wet(bool(p[12]) ? 0.0f : 1.0f);
	if (_nargs > 14)
		set_pan(p[14]);
}
예제 #2
0
// ---------------------------------------------------------------- subupdate --
void SPECTACLE2::subupdate()
{
	// NB: update EQ, deltime, fdback tables, so that live table draw will work,
	// and so that we can retrieve changing monolithic values instead of tables.
	// NB: input amp is updated in base class.
	double p[21];
	update(p, 21, 1 << 3 | 1 << 10 | 1 << 11 | 1 << 12 | 1 << 13
	                     | 1 << 14 | 1 << 15 | 1 << 16 | 1 << 18 | 1 << 20);
	set_oamp(p[3]);
	set_eq_freqrange(p[13], p[14]);
	set_freqrange(p[15], p[16]);
	if (_nargs > 18)
		set_wet(p[18]);
	if (_nargs > 20)
		set_pan(p[20]);

	if (_eqtable == NULL)
		_eqconst = p[10];
	if (_deltimetable == NULL)
		_deltimeconst = p[11];
	if (_feedbacktable == NULL)
		_feedbackconst = p[12];
}
예제 #3
0
int SPECTACLE2::subinit(double p[], int n_args)
{
	_eqtable = (double *) getPFieldTable(10, &_eqtablen);
	if (!_eqtable)
		_eqconst = p[10];

	int deltimetablen;
	_deltimetable = (double *) getPFieldTable(11, &deltimetablen);
	if (!_deltimetable)
		_deltimeconst = p[11];		// read later in this function

	int feedbacktablen;
	_feedbacktable = (double *) getPFieldTable(12, &feedbacktablen);
	if (!_feedbacktable)
		_feedbackconst = p[12];

	// Delay and feedback tables, if they exist, must be the same size.
	int cntltablen = 0;
	if (_deltimetable)
		cntltablen = deltimetablen;
	if (_feedbacktable) {
		cntltablen = feedbacktablen;
		if (_deltimetable && (feedbacktablen != deltimetablen))
			return die(instname(), "Delay time and feedback tables must be the "
		                          "same size.");
	}
	_control_table_size = cntltablen;

	int binmaptablen;
	double *binmaptable = (double *) getPFieldTable(17, &binmaptablen);
	if (binmaptable) {
		if (binmaptablen != _eqtablen || binmaptablen != _control_table_size)
			die(instname(), "The bin-mapping table (p17) must be the same size as "
			                "the EQ and delay tables (p10-12).");
		set_binmap_table(binmaptable);
		if (p[13] != 0.0
			|| (p[14] != 0.0 || p[14] != _nyquist)
			|| p[15] != 0.0
			|| (p[16] != 0.0 || p[16] != _nyquist))
			rtcmix_warn(instname(), "Use of the bin-mapping table ignores the freq. "
			                 "ranges set in p13-16.");
	}

	// Init delay minfreq and maxfreq, so that bin groups will be ready for use
	// below.  This calls update_bin_groups, which reads _control_table_size.
	set_freqrange(p[15], p[16]);

	// Compute maximum delay lag and create delay lines for FFT magnitude
	// and phase values.  Make ringdur at least as long as the longest
	// delay time.  Remember that these delays function at the decimation
	// rate, not at the audio rate, so the memory footprint is not as large
	// as you would expect -- about 44100 samples per second at fftlen=1024,
	// overlap=2 and SR=44100.

	// Set max delay time and bounds-check initial state of delay time array.
	// Also increase ringdur to accommodate longest delay time, if necessary.
	// Note that if user updates delay time table while running, values are
	// pinned to max delay time without notification.

	_maxdelsamps = long(kMaxDelayTime * SR / float(_decimation) + 0.5);
	float maxtime = 0.0f;
	float deltime = _deltimeconst;
	for (int i = 0; i <= _half_fftlen; i++) {
		if (_deltimetable)
			deltime = _deltimetable[_bin_groups[i]];
		if (deltime < 0.0f || deltime > kMaxDelayTime)
			return die(instname(), "Delay times must be between 0 and %g seconds.",
			                                                       kMaxDelayTime);
		if (deltime > maxtime)
			maxtime = deltime;
	}
	float ringdur = p[5];
	if (ringdur < maxtime)
		ringdur = maxtime;	// but will still cut off any trailing feedback
	set_ringdur(ringdur);

	DPRINT3("decimation=%d, _maxdelsamps=%ld, ringdur=%g\n",
											_decimation, _maxdelsamps, ringdur);
	return 0;
}
예제 #4
0
// --------------------------------------------------------------------- init --
int SpectacleBase::init(int fftlen, int windowlen, int overlap, float srate)
{
	_fftlen = fftlen;
	_window_len = windowlen;
	_overlap = overlap;

	// 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) {
		post("%s: FFT length must be a power of two <= %d. Setting to 1024...",
			instname(), kMaxFFTLen);
		_fftlen = 1024;
	}

	_half_fftlen = _fftlen / 2;

	// 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) {
		post("%s: Window length must be a power of two >= FFT length (%d)\n"
		           "and <= %d. Setting to 2048...",
				instname(), _fftlen, kMaxWindowLen);
		_window_len = _fftlen * 2;
	}

	// 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) {
		post("%s: Overlap must be a power of two between %d and %d. "
				"Setting to 2...",
		      instname(), kMinOverlap, kMaxOverlap);
		_overlap = 2;
	}

	_bin_groups = new int [_half_fftlen];

	set_srate(srate);
	set_freqrange(0.0f, 0.0f);

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

	_window_len_minus_decimation = _window_len - _decimation;

	DPRINT2("_fftlen=%d, _decimation=%d", _fftlen, _decimation);

	_input = new float [_window_len];            // interior input buffer
	_output = new float [_window_len];           // interior output buffer
	if (_input == NULL || _output == NULL)
		return -1;
	for (int i = 0; i < _window_len; i++)
		_input[i] = _output[i] = 0.0f;

	// Read index chases write index by _decimation; add 2 extra locations to
	// keep read point from stepping on write point.  Verify with asserts in
	// increment_out_*_index().
	_outframes = _decimation + 2;
	_out_read_index = _outframes - _decimation;
	_out_write_index = 0;
	_outbuf = new float [_outframes];
	if (_outbuf == NULL)
		return -1;
	for (int i = 0; i < _outframes; i++)
		_outbuf[i] = 0.0f;
	DPRINT1("_outframes: %d", _outframes);

	_anal_window = new float [_window_len];
	_synth_window = new float [_window_len];
	if (_anal_window == NULL || _synth_window == NULL)
		return -1;
	if (make_windows() != 0)
		return -1;

	_bucket = new Obucket(_decimation, process_wrapper, (void *) this);

	_fft = new Offt(_fftlen);
	_fft_buf = _fft->getbuf();

	return 0;
}