Esempio n. 1
0
// ---------------------------------------------------------- modify_analysis --
void SPECTEQ2::modify_analysis(bool reading_input)
{
	DPRINT1("modify_analysis: .............. reading_input=%d\n", reading_input);
#ifdef DUMP
	dump_anal_bins();
#endif

	for (int i = 0; i <= _half_fftlen; i++) {
		int index = i << 1;
		float eq = _eqtable ? _eqtable[_bin_groups[i]] : _eqconst;
		float mag = reading_input ? (_anal_bins[index] * _ampdb(eq)) : 0.0f;
		_anal_bins[index] = mag;
	}
}
Esempio n. 2
0
// ---------------------------------------------------------- modify_analysis --
void Spectacle::modify_analysis(bool reading_input)
{
	DPRINT("modify_analysis: .....................");

#ifdef PRINT_DELTIMES
	static float *prevdeltimes = NULL;
	if (prevdeltimes == NULL) {
		prevdeltimes = new float [_delay_table_size];
		post("\nmodify_analysis: delay times --------------------------");
		for (int i = 0; i < _delay_table_size; i++) {
			prevdeltimes[i] = _deltimetable[i];
			post("[%d] %f", i, _deltimetable[i]);
		}
 #ifdef PRINT_DELTIME_CHANGES
		post("\nmodify_analysis: delay time changes -------------------");
 #endif
	}
#endif

	const bool posteq = get_posteq();
	float eq;

	// NB: check EQ table size, rather than table pointer, to determine whether
	// we should use an EQ constant. Otherwise, there's a danger we could read
	// a null EQ table pointer, if set_eqtable called by non-perf thread.
	if (_control_table_size == 0)
		eq = _ampdb(_eqconst);

	for (int i = 0; i < _half_fftlen; i++) {
		int index = i << 1;

		if (_control_table_size > 0) {
			// EQ uses base class bin groups array.
			const int bg = _bin_groups[i];
			eq = _ampdb(_eqtable[bg]);
		}

		float real, imag;
		if (reading_input) {
		   if (posteq) {
				real = _fft_buf[index];
				imag = _fft_buf[index + 1];
			}
			else {
				real = _fft_buf[index] * eq;
				imag = _fft_buf[index + 1] * eq;
			}
		}
		else {
			real = 0.0f;
			imag = 0.0f;
		}

		const int bg = _delay_bin_groups[i];

		// NB: caller must assure that deltime is in range
		const float deltime = _deltimetable ? _deltimetable[bg] : _deltimeconst;

#ifdef PRINT_DELTIME_CHANGES
		if (deltime != prevdeltimes[bg]) {
			post("[%d] %f", bg, deltime);
			prevdeltimes[bg] = deltime;
		}
#endif

		if (deltime == 0.0f) {
		   if (posteq) {
				_fft_buf[index] = real * eq;
				_fft_buf[index + 1] = imag * eq;
			}
			else {
				_fft_buf[index] = real;
				_fft_buf[index + 1] = imag;
			}
		}
		else {
			const long delsamps = long((deltime * get_srate()) + 0.5)
			                                                     / _decimation;
			const float newreal = _real_delay[i]->getsamp(delsamps);
			const float newimag = _imag_delay[i]->getsamp(delsamps);
			const float feedback = _feedbacktable ? _feedbacktable[bg]
			                                      : _feedbackconst;
			if (feedback != 0.0) {
#ifdef ANTI_DENORM
				float fbsig = (newreal * feedback) + _antidenorm_offset;
				_real_delay[i]->putsamp(real + fbsig);
				fbsig = (newimag * feedback) + _antidenorm_offset;
				_imag_delay[i]->putsamp(imag + fbsig);
#else
				_real_delay[i]->putsamp(real + (newreal * feedback));
				_imag_delay[i]->putsamp(imag + (newimag * feedback));
#endif
			}
			else {
				_real_delay[i]->putsamp(real);
				_imag_delay[i]->putsamp(imag);
			}
		   if (posteq) {
				_fft_buf[index] = newreal * eq;
				_fft_buf[index + 1] = newimag * eq;
			}
			else {
				_fft_buf[index] = newreal;
				_fft_buf[index + 1] = newimag;
			}
		}
	}

	_fft_buf[1] = 0.0f;	// clear Nyquist real value

#ifdef ANTI_DENORM
	_antidenorm_offset = -_antidenorm_offset;
#endif
}
Esempio n. 3
0
// ---------------------------------------------------------- modify_analysis --
void SPECTACLE2::modify_analysis(bool reading_input)
{
	DPRINT1("modify_analysis: .............. reading_input=%d\n", reading_input);
#ifdef DUMP
	dump_anal_bins();
#endif

#ifdef PRINT_DELTIMES
	static float *prevdeltimes = NULL;
	if (prevdeltimes == NULL) {
		prevdeltimes = new float [_control_table_size];
		printf("\nmodify_analysis: delay times --------------------------\n");
		for (int i = 0; i < _control_table_size; i++) {
			prevdeltimes[i] = _deltimetable[i];
			printf("[%d] %f\n", i, _deltimetable[i]);
		}
 #ifdef PRINT_DELTIME_CHANGES
		printf("\nmodify_analysis: delay time changes -------------------\n");
 #endif
	}
#endif

	for (int i = 0; i <= _half_fftlen; i++) {
		int index = i << 1;

		float eq;
		if (_eqtable) {
			int bg = _eq_bin_groups ? _eq_bin_groups[i] : i;
			eq = _eqtable[bg];
		}
		else
			eq = _eqconst;

		// Delay time and feedback use base class bin groups array.
		const int bg = _bin_groups[i];

		float deltime = _deltimetable ? _deltimetable[bg] : _deltimeconst;
		deltime = _fclamp(0.0f, deltime, kMaxDelayTime);
#ifdef PRINT_DELTIME_CHANGES
		if (deltime != prevdeltimes[bg]) {
			printf("[%d] %f\n", bg, deltime);
			prevdeltimes[bg] = deltime;
		}
#endif

		float mag = reading_input ? (_anal_bins[index] * _ampdb(eq)) : 0.0f;
		float phase = _anal_bins[index + 1];

		if (deltime == 0.0f) {
			_anal_bins[index] = mag;
			_anal_bins[index + 1] = phase;
		}
		else {
			float feedback = _feedbacktable ? _feedbacktable[bg] : _feedbackconst;

			long delsamps = long((deltime * SR) + 0.5) / _decimation;

			// Not sure why this is necessary, but without it, delayed copies
			// sound distorted...

			if (_overlap > 1) {
				int remainder = delsamps % _overlap;
				if (remainder)
					delsamps -= remainder;
			}

			float newmag = _mag_delay[i]->getsamp(delsamps);
			float newphase = _phase_delay[i]->getsamp(delsamps);
			_anal_bins[index] = newmag;
			_anal_bins[index + 1] = newphase;
			_mag_delay[i]->putsamp(mag + (newmag * feedback));

			if (reading_input)
				_phase_delay[i]->putsamp(phase);
			else
				_phase_delay[i]->putsamp(newphase);
		}
	}
}