// ---------------------------------------------------------- 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; } }
// ---------------------------------------------------------- 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 }
// ---------------------------------------------------------- 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); } } }