Mercurial > hg > vamp-fanchirp
changeset 14:44b86c346a5a perf
Switch to Vamp SDK FFT implementation (it is close enough in performance - FFTs aren't really a bottleneck here - and simpler for the build) and use bqvec allocators
author | Chris Cannam |
---|---|
date | Tue, 02 Oct 2018 16:38:52 +0100 |
parents | 69069fc86e18 |
children | 0a860992b4f4 |
files | FChTransformF0gram.cpp FChTransformF0gram.h FChTransformUtils.cpp FChTransformUtils.h Makefile.mingw32 repoint repoint.ps1 |
diffstat | 7 files changed, 454 insertions(+), 206 deletions(-) [+] |
line wrap: on
line diff
--- a/FChTransformF0gram.cpp Tue Oct 02 16:38:16 2018 +0100 +++ b/FChTransformF0gram.cpp Tue Oct 02 16:38:52 2018 +0100 @@ -19,6 +19,11 @@ #include "FChTransformUtils.h" #include <math.h> #include <float.h> + +#include "bqvec/Allocators.h" + +using namespace breakfastquay; + //#define DEBUG #define MAX(x, y) (((x) > (y)) ? (x) : (y)) @@ -71,8 +76,45 @@ } -FChTransformF0gram::~FChTransformF0gram() { - // remeber to delete everything that deserves to +FChTransformF0gram::~FChTransformF0gram() +{ + if (!m_blockSize) { + return; // nothing was allocated + } + + deallocate(m_warpings.pos_int); + deallocate(m_warpings.pos_frac); + deallocate(m_warpings.chirp_rates); + + clean_LPF(); + + deallocate(m_timeWindow); + + deallocate(mp_HanningWindow); + + // Warping + deallocate(x_warping); + delete fft_xwarping; + deallocate(m_absFanChirpTransform); + deallocate(m_auxFanChirpTransform); + + // design_GLogS + deallocate(m_glogs_f0); + deallocate(m_glogs); + deallocate(m_glogs_n); + deallocate(m_glogs_index); + deallocate(m_glogs_posint); + deallocate(m_glogs_posfrac); + deallocate(m_glogs_interp); + deallocate(m_glogs_third_harmonic_posint); + deallocate(m_glogs_third_harmonic_posfrac); + deallocate(m_glogs_third_harmonic); + deallocate(m_glogs_fifth_harmonic_posint); + deallocate(m_glogs_fifth_harmonic_posfrac); + deallocate(m_glogs_fifth_harmonic); + deallocate(m_glogs_f0_preference_weights); + deallocate(m_glogs_median_correction); + deallocate(m_glogs_sigma_correction); } string @@ -479,7 +521,7 @@ /* f0 values of F0gram grid as string values */ vector<string> f0values; int ind = 0; - char f0String[10]; + char f0String[100]; while (ind < m_num_f0s) { sprintf(f0String, "%4.2f", m_f0s[ind]); f0values.push_back(f0String); @@ -491,13 +533,8 @@ d.identifier = "f0gram"; d.name = "F0gram: salience of f0s"; d.description = "This representation show the salience of the different f0s in the signal."; - d.unit = "Hertz"; d.hasFixedBinCount = true; - //d.binCount = m_num_f0s; - //d.binCount = m_blockSize/2+1; - //d.binCount = m_warp_params.nsamps_twarp/2+1; - //d.binCount = m_warpings.nsamps_torig; - d.binCount = m_f0_params.num_octs*m_f0_params.num_f0s_per_oct; + d.binCount = m_f0_params.num_octs * m_f0_params.num_f0s_per_oct; d.binNames = f0values; d.hasKnownExtents = false; d.isQuantized = false; @@ -511,7 +548,9 @@ bool FChTransformF0gram::initialise(size_t channels, size_t stepSize, size_t blockSize) { if (channels < getMinChannelCount() || - channels > getMaxChannelCount()) return false; + channels > getMaxChannelCount()) { + return false; + } // set blockSize and stepSize (but changed below) m_blockSize = blockSize; @@ -523,10 +562,6 @@ //m_blockSize = 4 * m_warp_params.nsamps_twarp; m_stepSize = floor(m_hop / m_warp_params.fact_over_samp); - /* initialise m_warp_params */ - // FChTF0gram:warping_design m_warpings = new warping_design; - /* initialise m_f0_params */ - /* initialise m_glogs_params */ design_GLogS(); @@ -538,9 +573,9 @@ design_time_window(); // Create Hanning window for warped signals - mp_HanningWindow = new double[m_warp_params.nsamps_twarp]; + mp_HanningWindow = allocate<double>(m_warp_params.nsamps_twarp); bool normalize = false; - hanning_window(mp_HanningWindow, m_warp_params.nsamps_twarp, normalize); + Utils::hanning_window(mp_HanningWindow, m_warp_params.nsamps_twarp, normalize); return true; } @@ -553,10 +588,10 @@ m_glogs_num_f0s = (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct + m_glogs_init_f0s; // Initialize arrays - m_glogs_f0 = new double[m_glogs_num_f0s]; - m_glogs = new double[m_glogs_num_f0s*m_warp_params.num_warps]; - m_glogs_n = new int[m_glogs_num_f0s]; - m_glogs_index = new int[m_glogs_num_f0s]; + m_glogs_f0 = allocate<double>(m_glogs_num_f0s); + m_glogs = allocate<double>(m_glogs_num_f0s*m_warp_params.num_warps); + m_glogs_n = allocate<int>(m_glogs_num_f0s); + m_glogs_index = allocate<int>(m_glogs_num_f0s); // Compute f0 values m_glogs_harmonic_count = 0; @@ -570,9 +605,9 @@ } // Initialize arrays for interpolation - m_glogs_posint = new int[m_glogs_harmonic_count]; - m_glogs_posfrac = new double[m_glogs_harmonic_count]; - m_glogs_interp = new double[m_glogs_harmonic_count]; + m_glogs_posint = allocate<int>(m_glogs_harmonic_count); + m_glogs_posfrac = allocate<double>(m_glogs_harmonic_count); + m_glogs_interp = allocate<double>(m_glogs_harmonic_count); // Compute int & frac of interpolation positions int aux_index = 0; @@ -589,31 +624,30 @@ // Third harmonic attenuation double aux_third_harmonic; - m_glogs_third_harmonic_posint = new int[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct]; - m_glogs_third_harmonic_posfrac = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct]; + m_glogs_third_harmonic_posint = allocate<int>((m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); + m_glogs_third_harmonic_posfrac = allocate<double>((m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); for (int i = 0; i < (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct; i++) { aux_third_harmonic = (double)i + (double)m_glogs_init_f0s - ((double)m_f0_params.num_f0s_per_oct)*log2(3.0); m_glogs_third_harmonic_posint[i] = (int)aux_third_harmonic; m_glogs_third_harmonic_posfrac[i] = aux_third_harmonic - (double)(m_glogs_third_harmonic_posint[i]); } - m_glogs_third_harmonic = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct]; + m_glogs_third_harmonic = allocate<double>((m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); // Fifth harmonic attenuation double aux_fifth_harmonic; - m_glogs_fifth_harmonic_posint = new int[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct]; - m_glogs_fifth_harmonic_posfrac = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct]; + m_glogs_fifth_harmonic_posint = allocate<int>((m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); + m_glogs_fifth_harmonic_posfrac = allocate<double>((m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); for (int i = 0; i < (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct; i++) { aux_fifth_harmonic = (double)i + (double)m_glogs_init_f0s - ((double)m_f0_params.num_f0s_per_oct)*log2(5.0); m_glogs_fifth_harmonic_posint[i] = (int)aux_fifth_harmonic; m_glogs_fifth_harmonic_posfrac[i] = aux_fifth_harmonic - (double)(m_glogs_fifth_harmonic_posint[i]); } - m_glogs_fifth_harmonic = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct]; + m_glogs_fifth_harmonic = allocate<double>((m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); // Normalization & attenuation windows - m_glogs_f0_preference_weights = new double[m_f0_params.num_octs*m_f0_params.num_f0s_per_oct]; - m_glogs_median_correction = new double[m_f0_params.num_octs*m_f0_params.num_f0s_per_oct]; - m_glogs_sigma_correction = new double[m_f0_params.num_octs*m_f0_params.num_f0s_per_oct]; - m_glogs_hf_smoothing_window = new double[m_warp_params.nsamps_twarp/2+1]; + m_glogs_f0_preference_weights = allocate<double>(m_f0_params.num_octs*m_f0_params.num_f0s_per_oct); + m_glogs_median_correction = allocate<double>(m_f0_params.num_octs*m_f0_params.num_f0s_per_oct); + m_glogs_sigma_correction = allocate<double>(m_f0_params.num_octs*m_f0_params.num_f0s_per_oct); double MIDI_value; for (int i = 0; i < m_f0_params.num_octs*m_f0_params.num_f0s_per_oct; i++) { MIDI_value = 69.0 + 12.0 * log2(m_glogs_f0[i + m_glogs_init_f0s]/440.0); @@ -623,16 +657,6 @@ m_glogs_median_correction[i] = m_glogs_params.median_poly_coefs[0]*(i+1.0)*(i+1.0) + m_glogs_params.median_poly_coefs[1]*(i+1.0) + m_glogs_params.median_poly_coefs[2]; m_glogs_sigma_correction[i] = 1.0 / (m_glogs_params.sigma_poly_coefs[0]*(i+1.0)*(i+1.0) + m_glogs_params.sigma_poly_coefs[1]*(i+1.0) + m_glogs_params.sigma_poly_coefs[2]); } - - double smooth_width = 1000.0; // hertz. - double smooth_aux = (double)(m_warp_params.nsamps_twarp/2+1)*(m_fmax-smooth_width)/m_fmax; - for (int i = 0; i < m_warp_params.nsamps_twarp/2+1; i++) { - if (i < smooth_aux) { - m_glogs_hf_smoothing_window[i] = 1.0; - } else { - m_glogs_hf_smoothing_window[i] = ((double)i - (double)m_warp_params.nsamps_twarp/2.0)*(-1.0/((double)(m_warp_params.nsamps_twarp/2+1)-smooth_aux)); - } - } } void @@ -655,30 +679,31 @@ // equivalent to: m_warpings.nsamps_torig = m_warp_params.fact_over_samp * m_blockSize; // time instants of the original signal frame - double t_orig[m_warpings.nsamps_torig]; - //float * t_orig = new float [m_warpings.nsamps_torig]; + double *t_orig = allocate<double>(m_warpings.nsamps_torig); for (int ind = 0; ind < m_warpings.nsamps_torig; ind++) { t_orig[ind] = ((double)(ind + 1) - (double)m_warpings.nsamps_torig / 2.0) / m_warpings.fs_orig; } // linear chirps warping definition as relative frequency deviation - //double * freq_relative = new double [m_warpings.nsamps_torig * m_warp_params.num_warps]; //TODO - double *freq_relative = new double [m_warpings.nsamps_torig * m_warp_params.num_warps]; + double *freq_relative = allocate<double>(m_warpings.nsamps_torig * m_warp_params.num_warps); define_warps_linear_chirps(freq_relative, t_orig); // maximum relative frequency deviation double freq_relative_max = 0; - for (int i = 0; i < m_warpings.nsamps_torig; i++) - for (int j = 0; j < m_warp_params.num_warps; j++) - if (freq_relative_max < freq_relative[j * m_warpings.nsamps_torig + i]) + for (int i = 0; i < m_warpings.nsamps_torig; i++) { + for (int j = 0; j < m_warp_params.num_warps; j++) { + if (freq_relative_max < freq_relative[j * m_warpings.nsamps_torig + i]) { freq_relative_max = freq_relative[j * m_warpings.nsamps_torig + i]; + } + } + } // sampling frequency of warped signal to be free of aliasing up to fmax m_warpings.fs_warp = 2 * m_fmax * freq_relative_max; // time instants of the warped signal frame - double t_warp[m_warp_params.nsamps_twarp]; + double *t_warp = allocate<double>(m_warp_params.nsamps_twarp); for (int ind = 0; ind < m_warp_params.nsamps_twarp; ind++) { t_warp[ind] = ((double)((int)(ind + 1)- (int)m_warp_params.nsamps_twarp / 2)) / (double)m_warpings.fs_warp; } @@ -714,16 +739,18 @@ } */ - delete [] freq_relative; + deallocate(freq_relative); + deallocate(t_orig); + deallocate(t_warp); + //output.close(); /* ============= FFTW PLAN DESIGN ============= */ // Initialize 2-d array for warped signals - x_warping = new double[m_warp_params.nsamps_twarp]; - m_absFanChirpTransform = (double*)fftw_malloc(sizeof (double) * m_warp_params.num_warps * (m_warp_params.nsamps_twarp/2 + 1)); - m_auxFanChirpTransform = (fftw_complex*)fftw_malloc(sizeof ( fftw_complex) * (m_warp_params.nsamps_twarp/2 + 1)); - plan_forward_xwarping = fftw_plan_dft_r2c_1d(m_warp_params.nsamps_twarp, x_warping, m_auxFanChirpTransform, FFTW_ESTIMATE); - + x_warping = allocate<double>(m_warp_params.nsamps_twarp); + m_absFanChirpTransform = allocate<double>(m_warp_params.num_warps * (m_warp_params.nsamps_twarp/2 + 1)); + m_auxFanChirpTransform = allocate<double>(2 * (m_warp_params.nsamps_twarp/2 + 1)); + fft_xwarping = new FFTReal(m_warp_params.nsamps_twarp); } void @@ -734,20 +761,20 @@ hypothesis: sampling frequency at the central point equals the original */ - m_warpings.pos_int = new int[m_warp_params.num_warps * m_warp_params.nsamps_twarp]; - m_warpings.pos_frac = new double[m_warp_params.num_warps * m_warp_params.nsamps_twarp]; + m_warpings.pos_int = allocate<int>(m_warp_params.num_warps * m_warp_params.nsamps_twarp); + m_warpings.pos_frac = allocate<double>(m_warp_params.num_warps * m_warp_params.nsamps_twarp); // vector of phase values - double *phi = new double[m_warpings.nsamps_torig]; + double *phi = allocate<double>(m_warpings.nsamps_torig); double aux; // warped positions - double *pos1 = new double[m_warp_params.nsamps_twarp*m_warp_params.num_warps]; + double *pos1 = allocate<double>(m_warp_params.nsamps_twarp*m_warp_params.num_warps); for (int i = 0; i < m_warp_params.num_warps; i++) { // integration of relative frequency to obtain phase values - cumtrapz(t_orig, freq_relative + i*(m_warpings.nsamps_torig), m_warpings.nsamps_torig, phi); + Utils::cumtrapz(t_orig, freq_relative + i*(m_warpings.nsamps_torig), m_warpings.nsamps_torig, phi); // centering of phase values to force original frequency in the middle aux = phi[m_warpings.nsamps_torig/2]; @@ -756,7 +783,7 @@ } //for // interpolation of phase values to obtain warped positions - interp1(phi, t_orig, m_warpings.nsamps_torig, t_warp, pos1 + i*m_warp_params.nsamps_twarp, m_warp_params.nsamps_twarp); + Utils::interp1(phi, t_orig, m_warpings.nsamps_torig, t_warp, pos1 + i*m_warp_params.nsamps_twarp, m_warp_params.nsamps_twarp); } // % previous sample index @@ -773,8 +800,8 @@ m_warpings.pos_frac[j] = pos1[j] - (double)(m_warpings.pos_int[j]); } //for - delete [] phi; - delete [] pos1; + deallocate(phi); + deallocate(pos1); } void @@ -786,7 +813,7 @@ if (m_warp_params.alpha_dist == 0) { // linear alpha values spacing - m_warpings.chirp_rates = new double [m_warp_params.num_warps]; + m_warpings.chirp_rates = allocate<double>(m_warp_params.num_warps); // WARNING m_warp_params.num_warps must be odd m_warpings.chirp_rates[0] = -m_warp_params.alpha_max; double increment = (double) m_warp_params.alpha_max / ((m_warp_params.num_warps - 1) / 2); @@ -799,7 +826,7 @@ } else { // log alpha values spacing - m_warpings.chirp_rates = new double [m_warp_params.num_warps]; + m_warpings.chirp_rates = allocate<double>(m_warp_params.num_warps); // force zero value int middle_point = (int) ((m_warp_params.num_warps - 1) / 2); @@ -823,22 +850,18 @@ } // compute relative frequency deviation - for (int i = 0; i < m_warpings.nsamps_torig; i++) - for (int j = 0; j < m_warp_params.num_warps; j++) + for (int i = 0; i < m_warpings.nsamps_torig; i++) { + for (int j = 0; j < m_warp_params.num_warps; j++) { freq_relative[j * m_warpings.nsamps_torig + i] = 1.0 + t_orig[i] * m_warpings.chirp_rates[j]; - //freq_relative[i * m_warpings.nsamps_torig + j] = 1.0 + t_orig[i] * m_warpings.chirp_rates[j]; - //freq_relative[i][j] = 1.0 + t_orig[i] * m_warpings.chirp_rates[j]; + } + } } void -FChTransformF0gram::design_LPF() { - - // in = (fftw_complex*) fftw_malloc(sizeof (fftw_complex) * tamanoVentana); - // out = (fftw_complex*) fftw_malloc(sizeof (fftw_complex) * tamanoVentana); - // in_window = (float*) fftw_malloc(sizeof (float) * tamanoVentana); - // p = fftw_plan_dft_1d(tamanoVentana, in, out, FFTW_FORWARD, FFTW_ESTIMATE); - double *lp_LPFWindow_aux = new double[m_blockSize/2+1]; - mp_LPFWindow = new double[m_blockSize/2+1]; +FChTransformF0gram::design_LPF() +{ + double *lp_LPFWindow_aux = allocate<double>(m_blockSize/2+1); + mp_LPFWindow = allocate<double>(m_blockSize/2+1); int i_max = (int) ((2.0*m_fmax/m_fs) * ( (double)m_blockSize / 2.0 + 1.0 )); for (int i = 0; i < m_blockSize/2+1; i++) { @@ -848,30 +871,15 @@ lp_LPFWindow_aux[i] = 1.0; } } - LPF_time = (double*)fftw_malloc(sizeof ( double) * m_warpings.nsamps_torig); - //memset((char*)LPF_time, 0, m_warpings.nsamps_torig * sizeof(double)); - // sustituyo el memset por un for: - for (int i = 0; i < m_warpings.nsamps_torig; i++) { - LPF_time[i] = 0.0; - } -#ifdef DEBUG - printf(" Corrio primer memset...\n"); -#endif - LPF_frequency = (fftw_complex*)fftw_malloc(sizeof ( fftw_complex) * (m_warpings.nsamps_torig/2 + 1)); //tamaño de la fft cuando la entrada es real - //memset((char*)LPF_frequency, 0, sizeof(fftw_complex) * (m_warpings.nsamps_torig/2 + 1)); - // sustituyo el memset por un for: - for (int i = 0; i < (m_warpings.nsamps_torig/2 + 1); i++) { - LPF_frequency[i][0] = 0.0; - LPF_frequency[i][1] = 0.0; - } -// for (int i=0; i<(m_blockSize/2+1); i++) { -// LPF_frequency[i] = new fftw_complex; -// } - plan_forward_LPF = fftw_plan_dft_r2c_1d(m_blockSize, LPF_time, LPF_frequency, FFTW_ESTIMATE); - plan_backward_LPF = fftw_plan_dft_c2r_1d(m_warpings.nsamps_torig, LPF_frequency, LPF_time, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); + + LPF_time = allocate_and_zero<double>(m_warpings.nsamps_torig); + LPF_frequency = allocate_and_zero<double>(2 * (m_warpings.nsamps_torig/2 + 1)); + + fft_forward_LPF = new FFTReal(m_blockSize); + fft_inverse_LPF = new FFTReal(m_warpings.nsamps_torig); int winWidth = 11; - double *lp_hanningWindow = new double[winWidth]; + double *lp_hanningWindow = allocate<double>(winWidth); double accum=0; for (int i = 0; i < winWidth; i++) { lp_hanningWindow[i]=0.5*(1.0-cos(2*M_PI*(double)(i+1)/((double)winWidth+1.0))); @@ -894,68 +902,36 @@ } } - delete[] lp_LPFWindow_aux; - delete[] lp_hanningWindow; + deallocate(lp_LPFWindow_aux); + deallocate(lp_hanningWindow); } -void FChTransformF0gram::apply_LPF() { - fftw_execute(plan_forward_LPF); +void FChTransformF0gram::apply_LPF() +{ + fft_forward_LPF->forward(LPF_time, LPF_frequency); + for (int i = 0; i < m_blockSize/2+1; i++) { - LPF_frequency[i][0]*=mp_LPFWindow[i]; - LPF_frequency[i][1]*=mp_LPFWindow[i]; + LPF_frequency[i*2] *= mp_LPFWindow[i] * m_warpings.nsamps_torig; + LPF_frequency[i*2 + 1] *= mp_LPFWindow[i] * m_warpings.nsamps_torig; } - fftw_execute(plan_backward_LPF); + + fft_inverse_LPF->inverse(LPF_frequency, LPF_time); // TODO ver si hay que hacer fftshift para corregir la fase respecto al centro del frame. // nota: además de aplicar el LPF, esta función resamplea la señal original. } -void FChTransformF0gram::clean_LPF() { - delete[] mp_LPFWindow; - - fftw_destroy_plan(plan_forward_LPF); - fftw_destroy_plan(plan_backward_LPF); - fftw_free(LPF_time); - fftw_free(LPF_frequency); +void FChTransformF0gram::clean_LPF() +{ + delete fft_forward_LPF; + delete fft_inverse_LPF; + deallocate(LPF_time); + deallocate(LPF_frequency); + deallocate(mp_LPFWindow); } -void FChTransformF0gram::reset() { - - // Clear buffers, reset stored values, etc - - delete [] m_warpings.pos_int; - delete [] m_warpings.pos_frac; - - clean_LPF(); - - delete [] m_timeWindow; - - delete [] mp_HanningWindow; - - // Warping - delete [] x_warping; - fftw_destroy_plan(plan_forward_xwarping); - fftw_free(m_absFanChirpTransform); - fftw_free(m_auxFanChirpTransform); - - // design_GLogS - delete [] m_glogs_f0; - delete [] m_glogs; - delete [] m_glogs_n; - delete [] m_glogs_index; - delete [] m_glogs_posint; - delete [] m_glogs_posfrac; - delete [] m_glogs_third_harmonic_posint; - delete [] m_glogs_third_harmonic_posfrac; - delete [] m_glogs_third_harmonic; - delete [] m_glogs_fifth_harmonic_posint; - delete [] m_glogs_fifth_harmonic_posfrac; - delete [] m_glogs_fifth_harmonic; - delete [] m_glogs_f0_preference_weights; - delete [] m_glogs_median_correction; - delete [] m_glogs_sigma_correction; - delete [] m_glogs_hf_smoothing_window; - +void FChTransformF0gram::reset() +{ } FChTransformF0gram::FeatureSet @@ -992,9 +968,6 @@ printf(" m_glogs_harmonic_count = %d.\n",m_glogs_harmonic_count); #endif - // int n = m_nfft/2 + 1; - // double *tbuf = in_window; - for (int i = 0; i < m_blockSize; i++) { LPF_time[i] = (double)(inputBuffers[0][i]) * m_timeWindow[i]; } @@ -1018,7 +991,7 @@ for (int i_warp = 0; i_warp < m_warp_params.num_warps; i_warp++) { // Interpolate - interp1q(LPF_time, (m_warpings.pos_int) + i_warp*m_warp_params.nsamps_twarp, m_warpings.pos_frac + i_warp*m_warp_params.nsamps_twarp, x_warping, m_warp_params.nsamps_twarp); + Utils::interp1q(LPF_time, (m_warpings.pos_int) + i_warp*m_warp_params.nsamps_twarp, m_warpings.pos_frac + i_warp*m_warp_params.nsamps_twarp, x_warping, m_warp_params.nsamps_twarp); // Apply window for (int i = 0; i < m_warp_params.nsamps_twarp; i++) { @@ -1026,20 +999,17 @@ } // Transform - fftw_execute(plan_forward_xwarping); + fft_xwarping->forward(x_warping, m_auxFanChirpTransform); // Copy result - //memcpy(m_absFanChirpTransform + i_warp*(m_warp_params.nsamps_twarp/2+1), m_auxFanChirpTransform, (m_warp_params.nsamps_twarp/2+1)*sizeof(fftw_complex)); asi como esta no funciona double *aux_abs_fcht = m_absFanChirpTransform + i_warp*(m_warp_params.nsamps_twarp/2+1); for (int i = 0; i < (m_warp_params.nsamps_twarp/2+1); i++) { - aux_abs_fcht[i] = log10(1.0 + 10.0*sqrt(m_auxFanChirpTransform[i][0]*m_auxFanChirpTransform[i][0]+m_auxFanChirpTransform[i][1]*m_auxFanChirpTransform[i][1])); - // smoothing high frequency values - //aux_abs_fcht[i] *= m_glogs_hf_smoothing_window[i]; + aux_abs_fcht[i] = log10(1.0 + 10.0*sqrt(m_auxFanChirpTransform[i*2]*m_auxFanChirpTransform[i*2]+m_auxFanChirpTransform[i*2+1]*m_auxFanChirpTransform[i*2+1])); } // ----------------------------------------------------------------------------------------- // GLogS - interp1q(aux_abs_fcht, m_glogs_posint, m_glogs_posfrac, m_glogs_interp, m_glogs_harmonic_count); + Utils::interp1q(aux_abs_fcht, m_glogs_posint, m_glogs_posfrac, m_glogs_interp, m_glogs_harmonic_count); int glogs_ind = 0; for (int i = 0; i < m_glogs_num_f0s; i++) { double glogs_accum = 0; @@ -1050,8 +1020,8 @@ } // Sub/super harmonic correction - interp1q(m_glogs + i_warp*m_glogs_num_f0s, m_glogs_third_harmonic_posint, m_glogs_third_harmonic_posfrac, m_glogs_third_harmonic, (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); - interp1q(m_glogs + i_warp*m_glogs_num_f0s, m_glogs_fifth_harmonic_posint, m_glogs_fifth_harmonic_posfrac, m_glogs_fifth_harmonic, (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); + Utils::interp1q(m_glogs + i_warp*m_glogs_num_f0s, m_glogs_third_harmonic_posint, m_glogs_third_harmonic_posfrac, m_glogs_third_harmonic, (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); + Utils::interp1q(m_glogs + i_warp*m_glogs_num_f0s, m_glogs_fifth_harmonic_posint, m_glogs_fifth_harmonic_posfrac, m_glogs_fifth_harmonic, (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct); for (int i = m_glogs_num_f0s-1; i >= m_glogs_init_f0s; i--) { m_glogs[i + i_warp*m_glogs_num_f0s] -= MAX(MAX(m_glogs[i-m_f0_params.num_f0s_per_oct + i_warp*m_glogs_num_f0s],m_glogs_third_harmonic[i-m_glogs_init_f0s]),m_glogs_fifth_harmonic[i-m_glogs_init_f0s]); //m_glogs[i] -= MAX(m_glogs[i-m_f0_params.num_f0s_per_oct],m_glogs_third_harmonic[i-m_glogs_init_f0s]); @@ -1074,14 +1044,6 @@ // ---------------------------------------------------------------------------------------------- for (int i=m_glogs_init_f0s; i< m_glogs_num_f0s - m_f0_params.num_f0s_per_oct; i++) { - //for (int i=0; i<(m_warp_params.nsamps_twarp/2+1); i++) { - //feature.values.push_back((float)(m_warpings.pos_int[i])+ (float)(m_warpings.pos_frac[i])); - //feature.values.push_back((float)(phi[i]*100000.0)); - //feature.values.push_back((float)(t_orig[i])); - //feature.values.push_back((float)(pos1[i])); - //feature.values.push_back((float)x_warping[i]); - //feature.values.push_back(m_absFanChirpTransform[i + ind_max_glogs*(m_warp_params.nsamps_twarp/2+1)]); - //feature.values.push_back((float)m_glogs[i+(long)ind_max_glogs*(long)m_glogs_num_f0s]); switch (m_f0gram_mode) { case 1: max_glogs = -DBL_MAX; @@ -1097,7 +1059,6 @@ feature.values.push_back((float)m_glogs[i+(int)ind_max_glogs*(int)m_glogs_num_f0s]); break; } - //feature.values.push_back((float)m_glogs_hf_smoothing_window[i]); } // ---------------------------------------------------------------------------------------------- @@ -1111,7 +1072,6 @@ return fs; //--------------------------------------------------------------------------- - //return FeatureSet(); } FChTransformF0gram::FeatureSet @@ -1123,8 +1083,8 @@ FChTransformF0gram::design_time_window() { int transitionWidth = (int)m_blockSize/128 + 1;; - m_timeWindow = new double[m_blockSize]; - double *lp_transitionWindow = new double[transitionWidth]; + m_timeWindow = allocate<double>(m_blockSize); + double *lp_transitionWindow = allocate<double>(transitionWidth); //memset(m_timeWindow, 1.0, m_blockSize); for (int i = 0; i < m_blockSize; i++) { @@ -1148,6 +1108,6 @@ } #endif - delete [] lp_transitionWindow; + deallocate(lp_transitionWindow); }
--- a/FChTransformF0gram.h Tue Oct 02 16:38:16 2018 +0100 +++ b/FChTransformF0gram.h Tue Oct 02 16:38:52 2018 +0100 @@ -22,8 +22,8 @@ #define _USE_MATH_DEFINES #include <cmath> #include <vamp-sdk/Plugin.h> +#include <vamp-sdk/FFT.h> #include <complex> -#include <fftw3.h> #include <iostream> #include <fstream> #include <string.h> @@ -31,6 +31,8 @@ using namespace std; using std::string; +using _VampPlugin::Vamp::FFTReal; + class FChTransformF0gram : public Vamp::Plugin { public: FChTransformF0gram(float inputSampleRate); @@ -137,9 +139,9 @@ // LPFWindow double *mp_LPFWindow; double *LPF_time; - fftw_complex *LPF_frequency; - fftw_plan plan_backward_LPF; - fftw_plan plan_forward_LPF; + double *LPF_frequency; + FFTReal *fft_forward_LPF; // two of these as they have different sizes + FFTReal *fft_inverse_LPF; // timeWindow double *m_timeWindow; // Warpings @@ -148,8 +150,8 @@ double *mp_HanningWindow; // FChT plan & transformed data structs double *m_absFanChirpTransform; - fftw_complex *m_auxFanChirpTransform; - fftw_plan plan_forward_xwarping; + double *m_auxFanChirpTransform; + FFTReal *fft_xwarping; // GLogS double *m_glogs_f0; double *m_glogs; @@ -170,7 +172,6 @@ double *m_glogs_f0_preference_weights; double *m_glogs_median_correction; double *m_glogs_sigma_correction; - double *m_glogs_hf_smoothing_window; // auxiliar methods void design_GLogS(); void design_FChT();
--- a/FChTransformUtils.cpp Tue Oct 02 16:38:16 2018 +0100 +++ b/FChTransformUtils.cpp Tue Oct 02 16:38:52 2018 +0100 @@ -19,7 +19,8 @@ #include "FChTransformUtils.h" #include <math.h> -void cumtrapz(const double *x, const double *y, int N, double *accum) +void +Utils::cumtrapz(const double *x, const double *y, int N, double *accum) /*Trapezoidal Integrator: 1/2(b-a)(F(a)+F(b))*/ { accum[0]=0.0; @@ -29,7 +30,8 @@ } -void interp1(const double *x1, const double *y1, int N1, const double *x2, double *y2, int N2){ +void +Utils::interp1(const double *x1, const double *y1, int N1, const double *x2, double *y2, int N2){ /*1-D linear interpolation*/ for (int i = 0; i < N2; i++) { @@ -54,15 +56,8 @@ } -void interp1q(const double *y1, const int *x2_int, const double *x2_frac, double *y2, int N2){ - - for(int i=0;i<N2;i++){ - y2[i] = y1[x2_int[i]]*(1.0-x2_frac[i])+y1[x2_int[i]+1]*x2_frac[i]; - } // for - -} - -void hanning_window(double *p_window, int n, bool normalize) { +void +Utils::hanning_window(double *p_window, int n, bool normalize) { double accum=0; for (int i = 0; i < n; i++) {
--- a/FChTransformUtils.h Tue Oct 02 16:38:16 2018 +0100 +++ b/FChTransformUtils.h Tue Oct 02 16:38:52 2018 +0100 @@ -15,12 +15,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef FCHTRANSFORMUTILS_H +#define FCHTRANSFORMUTILS_H + #include <string.h> -void interp1(const double *x1,const double *y1, int N1, const double *x2, double *y2, int N2); +class Utils +{ +public: + static void interp1(const double *x1,const double *y1, int N1, const double *x2, double *y2, int N2); -void interp1q(const double *y1, const int *x2_int, const double *x2_frac, double *y2, int N2); + static void interp1q(const double *y1, const int *x2_int, const double *x2_frac, double *y2, int N2){ + for(int i=0;i<N2;i++){ + y2[i] = y1[x2_int[i]]*(1.0-x2_frac[i])+y1[x2_int[i]+1]*x2_frac[i]; + } // for + } -void cumtrapz(const double *x, const double *y, int N, double *accum); + static void cumtrapz(const double *x, const double *y, int N, double *accum); -void hanning_window(double *p_window, int n, bool normalize); + static void hanning_window(double *p_window, int n, bool normalize); +}; + +#endif +
--- a/Makefile.mingw32 Tue Oct 02 16:38:16 2018 +0100 +++ b/Makefile.mingw32 Tue Oct 02 16:38:52 2018 +0100 @@ -17,16 +17,11 @@ # For a debug build... -CFLAGS := -Wall -Wextra -g +#CFLAGS := -Wall -Wextra -g # ... or for a release build -#CFLAGS := -Wall -Wextra -O3 -ftree-vectorize - - -# Location of Vamp plugin SDK relative to the project directory - -VAMPSDK_DIR := ../vamp-plugin-sdk +CFLAGS := -Wall -Wextra -O3 -ftree-vectorize # Libraries and linker flags required by plugin: add any -l<library>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint Tue Oct 02 16:38:52 2018 +0100 @@ -0,0 +1,166 @@ +#!/bin/bash + +# Disable shellcheck warnings for useless-use-of-cat. UUOC is good +# practice, not bad: clearer, safer, less error-prone. +# shellcheck disable=SC2002 + +sml="$REPOINT_SML" + +set -eu + +# avoid gussying up output +export HGPLAIN=true + +mydir=$(dirname "$0") +program="$mydir/repoint.sml" + +hasher= +local_install= +if [ -w "$mydir" ]; then + if echo | sha256sum >/dev/null 2>&1 ; then + hasher=sha256sum + local_install=true + elif echo | shasum >/dev/null 2>&1 ; then + hasher=shasum + local_install=true + else + echo "WARNING: sha256sum or shasum program not found" 1>&2 + fi +fi + +if [ -n "$local_install" ]; then + hash=$(echo "$sml" | cat "$program" - | $hasher | cut -c1-16) + gen_sml=$mydir/.repoint-$hash.sml + gen_out=$mydir/.repoint-$hash.bin + trap 'rm -f $gen_sml' 0 +else + gen_sml=$(mktemp /tmp/repoint-XXXXXXXX.sml) + gen_out=$(mktemp /tmp/repoint-XXXXXXXX.bin) + trap 'rm -f $gen_sml $gen_out' 0 +fi + +if [ -x "$gen_out" ]; then + exec "$gen_out" "$@" +fi + +# We need one of Poly/ML, SML/NJ, MLton, or MLKit. Since we're running +# a single-file SML program as if it were a script, our order of +# preference is usually based on startup speed. An exception is the +# local_install case, where we retain a persistent binary + +if [ -z "$sml" ]; then + if [ -n "$local_install" ] && mlton 2>&1 | grep -q 'MLton'; then + sml="mlton" + elif sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then + sml="smlnj" + # We would prefer Poly/ML to SML/NJ, except that Poly v5.7 has a + # nasty bug that occasionally causes it to deadlock on startup. + # That is fixed in v5.7.1, so we could promote it up the order + # again at some point in future + elif echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then + sml="polyml" + elif mlton 2>&1 | grep -q 'MLton'; then + sml="mlton" + # MLKit is at the bottom because it leaves compiled files around + # in an MLB subdir in the current directory + elif mlkit 2>&1 | grep -q 'MLKit'; then + sml="mlkit" + else cat 1>&2 <<EOF + +ERROR: No supported SML compiler or interpreter found +EOF + cat 1>&2 <<EOF + + The Repoint external source code manager needs a Standard ML (SML) + compiler or interpreter to run. + + Please ensure you have one of the following SML implementations + installed and present in your PATH, and try again. + + 1. Standard ML of New Jersey + - may be found in a distribution package called: smlnj + - executable name: sml + + 2. Poly/ML + - may be found in a distribution package called: polyml + - executable name: poly + + 3. MLton + - may be found in a distribution package called: mlton + - executable name: mlton + + 4. MLKit + - may be found in a distribution package called: mlkit + - executable name: mlkit + +EOF + exit 2 + fi +fi + +arglist="" +for arg in "$@"; do + if [ -n "$arglist" ]; then arglist="$arglist,"; fi + if echo "$arg" | grep -q '["'"'"']' ; then + arglist="$arglist\"usage\"" + else + arglist="$arglist\"$arg\"" + fi +done + +case "$sml" in + polyml) + if [ -n "$local_install" ] && polyc --help >/dev/null 2>&1 ; then + if [ ! -x "$gen_out" ]; then + polyc -o "$gen_out" "$program" + fi + "$gen_out" "$@" + else + echo 'use "'"$program"'"; repoint ['"$arglist"'];' | + poly -q --error-exit + fi ;; + mlton) + if [ ! -x "$gen_out" ]; then + echo "[Precompiling Repoint binary...]" 1>&2 + echo "val _ = main ()" | cat "$program" - > "$gen_sml" + mlton -output "$gen_out" "$gen_sml" + fi + "$gen_out" "$@" ;; + mlkit) + if [ ! -x "$gen_out" ]; then + echo "[Precompiling Repoint binary...]" 1>&2 + echo "val _ = main ()" | cat "$program" - > "$gen_sml" + mlkit -output "$gen_out" "$gen_sml" + fi + "$gen_out" "$@" ;; + smlnj) + cat "$program" | ( + cat <<EOF +val smlrun__cp = + let val x = !Control.Print.out in + Control.Print.out := { say = fn _ => (), flush = fn () => () }; + x + end; +val smlrun__prev = ref ""; +Control.Print.out := { + say = fn s => + (if String.isSubstring " Error" s + then (Control.Print.out := smlrun__cp; + (#say smlrun__cp) (!smlrun__prev); + (#say smlrun__cp) s) + else (smlrun__prev := s; ())), + flush = fn s => () +}; +EOF + cat - + cat <<EOF +val _ = repoint [$arglist]; +val _ = OS.Process.exit (OS.Process.success); +EOF + ) > "$gen_sml" + CM_VERBOSE=false sml "$gen_sml" ;; + *) + echo "ERROR: Unknown SML implementation name: $sml" 1>&2; + exit 2 ;; +esac +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint.ps1 Tue Oct 02 16:38:52 2018 +0100 @@ -0,0 +1,117 @@ +<# + +.SYNOPSIS +A simple manager for third-party source code dependencies. +Run "repoint help" for more documentation. + +#> + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = "Stop" +$env:HGPLAIN = "true" + +$sml = $env:REPOINT_SML + +$mydir = Split-Path $MyInvocation.MyCommand.Path -Parent +$program = "$mydir/repoint.sml" + +# We need either Poly/ML or SML/NJ. No great preference as to which. + +# Typical locations +$env:PATH = "$env:PATH;C:\Program Files (x86)\SMLNJ\bin;C:\Program Files\Poly ML;C:\Program Files (x86)\Poly ML" + +if (!$sml) { + if (Get-Command "sml" -ErrorAction SilentlyContinue) { + $sml = "smlnj" + } elseif (Get-Command "polyml" -ErrorAction SilentlyContinue) { + $sml = "poly" + } else { + echo @" + +ERROR: No supported SML compiler or interpreter found + + The Repoint external source code manager needs a Standard ML (SML) + compiler or interpreter to run. + + Please ensure you have one of the following SML implementations + installed and present in your PATH, and try again. + + 1. Standard ML of New Jersey + - executable name: sml + + 2. Poly/ML + - executable name: polyml + +"@ + exit 1 + } +} + +if ($args -match "'""") { + $arglist = '["usage"]' +} else { + $arglist = '["' + ($args -join '","') + '"]' +} + +if ($sml -eq "poly") { + + $program = $program -replace "\\","\\\\" + echo "use ""$program""; repoint $arglist" | polyml -q --error-exit | Out-Host + + if (-not $?) { + exit $LastExitCode + } + +} elseif ($sml -eq "smlnj") { + + $lines = @(Get-Content $program) + $lines = $lines -notmatch "val _ = main ()" + + $intro = @" +val smlrun__cp = + let val x = !Control.Print.out in + Control.Print.out := { say = fn _ => (), flush = fn () => () }; + x + end; +val smlrun__prev = ref ""; +Control.Print.out := { + say = fn s => + (if String.isSubstring "Error" s orelse String.isSubstring "Fail" s + then (Control.Print.out := smlrun__cp; + (#say smlrun__cp) (!smlrun__prev); + (#say smlrun__cp) s) + else (smlrun__prev := s; ())), + flush = fn s => () +}; +"@ -split "[\r\n]+" + + $outro = @" +val _ = repoint $arglist; +val _ = OS.Process.exit (OS.Process.success); +"@ -split "[\r\n]+" + + $script = @() + $script += $intro + $script += $lines + $script += $outro + + $tmpfile = ([System.IO.Path]::GetTempFileName()) -replace "[.]tmp",".sml" + + $script | Out-File -Encoding "ASCII" $tmpfile + + $env:CM_VERBOSE="false" + + sml $tmpfile + + if (-not $?) { + del $tmpfile + exit $LastExitCode + } + + del $tmpfile + +} else { + + "Unknown SML implementation name: $sml" + exit 2 +}